Blog>
Snippets

Progress Bar for Navigation Loading State

Implement a progress bar that signals the loading state when navigating between routes in Next.js 14.
import { useRouter } from 'next/router';
import { useState, useEffect } from 'react';
import NProgress from 'nprogress'; // Ensure NProgress package is installed (`npm install nprogress`)

export default function ProgressBar() {
  const router = useRouter();
  const [loading, setLoading] = useState(false);

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

    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);
    };
  }, [router]);

  useEffect(() => {
    if (loading) {
      NProgress.start();
    } else {
      NProgress.done();
    }
  }, [loading]);

  return null;
}
This JS code sets up a progress bar with NProgress that reacts to Next.js router events. It handles the start and completion of page navigations, displaying a loading bar on top of the page.
import '../node_modules/nprogress/nprogress.css'; // Load NProgress styles
Include this import statement at the top of your custom _app.js file to ensure the NProgress CSS is loaded.
<ProgressBar />
Add this JSX tag in your custom _app.js component to incorporate the Progress Bar into the layout.