DEV Community

Cover image for Show a loading screen when changing pages in Next.js App router
Ajith Kumar P M
Ajith Kumar P M

Posted on

Show a loading screen when changing pages in Next.js App router

Switching from the page router to the app router was quite a challenge for me. It wasn't just due to Next.js itself— in fact, the transition from the old page router code to the new one was fairly smooth. The real difficulty came from the other tools we were using. Apollo Client still isn't fully supported , and @module-federation/nextjs-m is now in maintenance, and more. Despite all these challenges, I actually ended up liking app router. One issue I'm still having is with the changes they made new useRouter(the one from next/navigation).
I ran two identical React apps, one using TanStack Routing and the other with Next.js App Router. Immediately, I noticed a significant delay in page transitions in Next.js. The lag in development mode is actually addressed by the Next.js team here. However, I found that the page transition delay was still noticeably slower in production, compared to the TanStack Router example.

As a result, my next step was to implement a page transition loader in the app. Most implementations I came across used router.events to set up a progress bar on route changes. Unfortunately, the newer versions of Next.js no longer support this approach. In the following section, I'll show you how to set up a progress bar for route changes in Next.js App Router using react-transition-progress

npm install react-transition-progress framer-motion
Enter fullscreen mode Exit fullscreen mode

Internally they are using framer motion for animations, which I found completely overkill for it's purpose.

Add the following to the layout.tsx

<ProgressBarProvider>
 <ProgressBar className={css({
    position: 'absolute',
    top: '0',
    height: '5px',
    backgroundColor: 'black',
    borderRightRadius: '100',
    boxShadow: '0 10px 15px -3px black, 0 4px 6px -2px black',
})} />
         {children}
 </ProgressBarProvider>
Enter fullscreen mode Exit fullscreen mode

For styling I'm using panda css, just change it to whatever you are using

Now change all your router.push statements into something like

// import {startTransition} from "react"
// import { useProgress } from "react-transition-progress";
// const startProgress = useProgress();
...
 startTransition(async () => {
            startProgress();
            router.push("/")
          });
...
Enter fullscreen mode Exit fullscreen mode

Also instead of next's default Link component use Link from react-transition-progress

Top comments (0)