dev-resources.site
for different kinds of informations.
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
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>
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("/")
});
...
Also instead of next's default Link
component use Link
from react-transition-progress
Featured ones: