DEV Community

James Perkins
James Perkins

Posted on • Originally published at jamesperkins.dev

Page to page loading in next.js

I am a huge advocate of minimalist websites, I don't hate heavily overly designed websites with animations and designs but they have a place. Talking of animations, one thing you do want is a way to handle moving between pages and loading data.

Handling loading through next/router

One great feature of next/router is the ability to tap into the events that happen during a route change. This means you can use these to handle loading. So what are the events we need? We need route change events

routeChangeStart
routeChangeComplete
routeChangeError
Enter fullscreen mode Exit fullscreen mode

With these three events and useEffect and useState you can handle each route change on your application. For example

function Loading() {
  const router = useRouter();

  const [loading, setLoading] = useState(false);

  useEffect(() => {
      const handleStart = (url) => (url !== router.asPath) && setLoading(true);
      const handleComplete = (url) => (url === router.asPath) && setTimeout(() =>{setLoading(false)},2000);

      router.events.on('routeChangeStart', handleStart)
      router.events.on('routeChangeComplete', handleComplete)
      router.events.on('routeChangeError',  handleComplete)

      return () => {
          router.events.off('routeChangeStart', handleStart)
          router.events.off('routeChangeComplete', handleComplete)
          router.events.off('routeChangeError', handleComplete)
      }
  })

  return loading && (
    <div>loading</>
  )
}
Enter fullscreen mode Exit fullscreen mode

What is happening?

Now you have an example to look at, let us talk about what we are doing to make a loading function. First we are setting a state of loading as a boolean. This allows you to easily swap between it is and is not loading, we are then using useEffect to power the checks. The useEffect here has two functions one to handle the starting and one to handle when it is finished, we then use the router.events mentioned above to decide what function should run. If we are starting, it should run handleStart which sets loading to true. Otherwise it's finished and we should set loading to false.

Finally we have a conditonal renderer that only shows if it is indeed loading.

Top comments (3)

Collapse
 
fuhadkalathingal profile image
Fuhad Kalathingal

hey sir,
can you add search function in my github repo...
can you take it as a challenge and help me ?

Collapse
 
svgatorapp profile image
SVGator

👏

Collapse
 
westernal profile image
Ali Navidi

Great article, thanks!