,

Next Js NProgress – Add Global Loading Bar Tutorial with Examples

In this Next js tutorial, you will learn how to add a global loading bar in the Next js application using the NProgress module for showing a progress bar to indicate any asynchronous job. Showing the loader progress bar is a very important element in UI to indicate user if any process is going on…

By.

•

min read

In this Next js tutorial, you will learn how to add a global loading bar in the Next js application using the NProgress module for showing a progress bar to indicate any asynchronous job.

Showing the loader progress bar is a very important element in UI to indicate user if any process is going on and will complete in a definite period.

In front-end applications, which are mostly data-driven and data is fetched from a remote server its always a good practice to show a loader progress bar to the user. In the Next Js application, you can easily implement a progress horizontal loading bar using the NProgress package module.

[lwptoc]

 

What is Nprogress?

NProgress is a JavaScript library which provides an elegant progress bar for applications. The progress bar can easily be customized using CSS styles. It basic design is inspired by Google, YouTube, and Medium.

NProgress displays a progress bar at the top of the page when the page is loading or when some operation is in progress (like an AJAX request). It helps to improve the user experience, as users get visible feedback that something is in progress.

 

How to add the NProgress bar in the Next Js application?

Follow these quick steps to add the NProgess bar in the Next js application:

Step 1 – Create Next js application

Step 2 – Install NProgress in the Application

Step 3 – Add CSS Style for NProgress

Step 4 – Adding loadData function

Step 5 – Other Use-Cases with Example

Step 6 – Run the Application

 

 

Step 1 – Create Next js application

First create a new Next js application by executing the below command:

npx create-next-app@11 my-app

 

Enter into the application directory:

cd my-app

 

Step 2 – Install NProgress in the Application

Thereafter we will install the NProgress package module. Execute the following command to install the NProgress library into the application:

npm install nprogress

 

Step 3 – Add CSS Style for NProgress

The amazing thing about NProgress is you can easily customize the colour and style of NProgress bar. Open the existing CSS file for example globals.css and add the following style at the bottom:

/* NProgress Style */

#nprogress {
  pointer-events: none;
}

#nprogress .bar {
  background: rgb(255, 0, 0);

  position: fixed;
  z-index: 1031;
  top: 0;
  left: 0;

  width: 100%;
  height: 5px;
}

#nprogress .peg {
  display: block;
  position: absolute;
  right: 0px;
  width: 100px;
  height: 100%;
  box-shadow: 0 0 10px rgb(255, 0, 0), 0 0 5px rgb(255, 0, 0);
  opacity: 1.0;

  transform: rotate(3deg) translate(0px, -4px);
}

 

Step 4 – Adding loadData function

Now we will add the loadData function to simulate the real HTTP or Ajax asynchronous calls and display the progress loading bar. Open the pages/index.js file and update it with following:

// pages/index.js

import { useEffect, useState } from "react";
import NProgress from "nprogress";

// Simulate a delay
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

async function loadData() {
  NProgress.start(); // Start the progress bar

  try {
    await delay(5000); // simulate a delay of 2 seconds
    const response = await fetch("/api/data"); // Fetching data
    const data = await response.json();
    NProgress.done(); // End the progress bar on successful fetch
    return data;
  } catch (error) {
    NProgress.done(); // End the progress bar on error
    throw error;
  }
}

export default function Home() {
  const [data, setData] = useState(null);

  useEffect(() => {
    loadData()
      .then((data) => setData(data))
      .catch((error) => console.error(error));
  }, []);

  return <div>{data ? <div>Data Loaded!</div> : <div>Loading...</div>}</div>;
}

 

Step 5 – Other Use-Cases with Example

Lets have a look on other use-cases of NProgress bar and its sample example implementations:

 

1 – Show Loader on Routing the Pages

The page load indicator is usually set in _app.js file where all route changes occur:

// _app.js

import Router from 'next/router'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'

Router.events.on('routeChangeStart', () => NProgress.start());
Router.events.on('routeChangeComplete', () => NProgress.done());
Router.events.on('routeChangeError', () => NProgress.done());

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

export default MyApp

 

2 – Asynchronous Operation Indicator

As we discussed, NProgresss can be displayed during HTTP calls as shown below. The progress bar is shown during the fetch operation.

// pages/index.js

import { useEffect, useState } from 'react'
import NProgress from 'nprogress'

async function fetchData() {
  NProgress.start();
  const res = await fetch('/api/data');
  const json = await res.json();
  NProgress.done();
  return json;
}

function HomePage() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetchData().then(data => setData(data));
  }, []);

  // Render the data
  // ...
}

export default HomePage

 

3 – File Upload Indicator

Users can be shown a progress bar when Uploading or Downloading processes on UI.

// pages/upload.js

import NProgress from 'nprogress'

function uploadFile(file) {
  NProgress.start();

  // Create a FormData object and append the file
  const formData = new FormData();
  formData.append('file', file);

  // Send the file to your API
  fetch('/api/upload', {
    method: 'POST',
    body: formData
  })
  .then(() => NProgress.done())
  .catch(() => NProgress.done());
}

function UploadPage() {
  const onFileChange = (event) => {
    uploadFile(event.target.files[0]);
  };

  return (
    <input type="file" onChange={onFileChange} />
  );
}

export default UploadPage

 

4 – Long Running Process Indicator

Here is another example where we will simulate some dummy long-running process which sleeps after 5 seconds:

// pages/long-process.js

import { useEffect } from 'react'
import NProgress from 'nprogress'

async function longRunningProcess() {
  NProgress.start();

  // Simulate a long running process
  await new Promise(resolve => setTimeout(resolve, 5000));

  NProgress.done();
}

function LongProcessPage() {
  useEffect(() => {
    longRunningProcess();
  }, []);

  return (
    <div>Long running process...</div>
  );
}

export default LongProcessPage

 

5 – Custom Loading Indicator

A custom loading indicator can be used in specific needs. Here’s an example of a function that takes a callback and shows the progress bar while the callback is running.

// pages/custom-loading.js

import { useEffect, useState } from 'react'
import NProgress from 'nprogress'

async function withLoading(callback) {
  NProgress.start();

  try {
    await callback();
  } finally {
    NProgress.done();
  }
}

function CustomLoadingPage() {
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    const task = async () => {
      setIsLoading(true);
      await new Promise(resolve => setTimeout(resolve, 2000));
      setIsLoading(false);
    };

    withLoading(task);
  }, []);

  return (
    <div>{isLoading ? 'Loading...' : 'Task completed!'}</div>
  );
}

export default CustomLoadingPage

 

Step 6) Run Next js Application

Now you can run your Next js application by executing the below command:

npm run dev

 

Bottom Line

We discussed how to implement the NProgress loading bar in the Next Js application with each and every possible use case. In various examples, we discussed Setting up Routing to show the progress bar, Handling Ajax HTTP calls, File uploaded and other examples to use the NProgress loading bar.

Moreover, we customized the progress bar style using CSS which can be very useful to modify the UI layout of the progress bar according to your own themes.

Leave a Reply

Your email address will not be published. Required fields are marked *