andersbs
andersbs

Reputation: 187

How to access the url or page that is currently loading on navigation with Next.js

I want to add per page custom skeleton loaders on page navigation. To do that I need to know which page is currently being loaded.

I have tried this approach with useRouter:

//_app.tsx
useEffect(() => {
    const handleStart = () => setLoading(true);
    const handleComplete = () => setLoading(false);
    router.events.on('routeChangeStart', handleStart);
    router.events.on('routeChangeComplete', handleComplete);
    router.events.on('routeChangeError', handleComplete);

    console.log(router);
  }, [router]);

The routechange events are being triggered when starting to navigate, but the route console log does not print the page I'm going to until it's already loaded. I have noticed that the url in the browser is not changing before the page loading is completed.

I need a way to get the current loading page (the pathname or anything that can tell me what is currently loading). Is this even possible?

I am using Next.js, TypeScript and SSR.

Upvotes: 2

Views: 2643

Answers (1)

juliomalves
juliomalves

Reputation: 50458

You can access the path in the routeChangeStart handler function as it receives the URL of the route you're navigating to when fired in its first argument.

useEffect(() => {
    const handleStart = (url: string) => {
        console.log(url); // Will log the path to the page being navigated to
        setLoading(true);
    };
    const handleComplete = () => setLoading(false);
    router.events.on('routeChangeStart', handleStart);
    router.events.on('routeChangeComplete', handleComplete);
    router.events.on('routeChangeError', handleComplete);
    
    // Cleanup event listeners
    return () => {
        router.events.off('routeChangeStart', handleStart);
        router.events.off('routeChangeComplete', handleComplete);
        router.events.off('routeChangeError', handleComplete);
    }
}, [router]);

As a side note, it's good practice to cleanup any event listeners set beforehand in the useEffect's cleanup phase.

Upvotes: 2

Related Questions