How to add progress bar in Nextjs 14 (using router.push)

April 5, 2024 (2mo ago)

With the recent changes in nextjs 14 router, the way of adding a progress bar has also changed, since there are no router events in next/navigation.

In this tutorial, we will cover how to show a progress bar on router.push.

Let's get started by creating a nextjs project.

  • Go to your terminal :
npx create-next-app@latest

On installation, you'll see the following prompts :

What is your project named? my-app Would you like to use TypeScript? No / Yes Would you like to use ESLint? No / Yes Would you like to use Tailwind CSS? No / Yes Would you like to use `src/` directory? No / Yes Would you like to use App Router? (recommended) No / Yes Would you like to customize the default import alias (@/*)? No / Yes

We will use a package called nprogress to show the progress bar. Go inside your project directory and install it.

cd my-app && npm i nprogress

Start the project :

npm run dev

Add the css for nprogress in the global.css file.

@import 'nprogress/nprogress.css';

Remove the boiler plate code in page.tsx and replace it with the following :

export default function Home() { return <main>This is the home page.</main>; }

Create a folder named components inside the src folder.

Create a Navbar.tsx file inside the components folder and add the following :

'use client'; import { usePathname, useRouter } from 'next/navigation'; import Nprogress from 'nprogress'; import { useEffect } from 'react'; const Navbar = () => { const router = useRouter(); const pathname = usePathname(); useEffect(() => { Nprogress.done(); }, [pathname]); const handleRouter = (route: string) => { // Don't show progress bar if the route has not changed. if (route !== pathname) { Nprogress.start(); } router.push(route); }; return ( <nav> <ul className="flex items-center space-x-4 justify-center py-5"> <li className="cursor-pointer" onClick={() => handleRouter('/')}> Home </li> <li className="cursor-pointer" onClick={() => handleRouter('/projects')} > Projects </li> </ul> </nav> ); }; export default Navbar;

The code above shows the progress bar on router.push and after the new page is loaded the progress bar is removed.

Now let us add the navbar file in the layout.tsx file by updating it as shown below :

import type { Metadata } from 'next'; import { Inter } from 'next/font/google'; import './globals.css'; import Navbar from '@/components/Navbar'; const inter = Inter({ subsets: ['latin'] }); export const metadata: Metadata = { title: 'Create Next App', description: 'Generated by create next app', }; export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode, }>) { return ( <html lang="en"> <body className={inter.className}> <Navbar /> <div className="py-5 flex justify-center items-center">{children}</div> </body> </html> ); }

Let us now create a projects page.

Create a folder named projects inside the app folder and add a page.tsx file

const ProjectsPage = () => { return <div>This is the projects page.</div>; }; export default ProjectsPage;

You should now see a progress bar when you click on the projects link that navigates to the projects page.

Congratulations. You have now created a nextjs project with a progress bar.