How to Add Spinner Loader in NextJS?

We can use conditional rendering to only display the spinner when certain conditions are met, such as when data is being fetched from an API. Additionally, we can use CSS to style the spinner and make it match the overall design of our website.

What is NextJS?

Next.js is a JavaScript framework for building server-rendered React applications. It provides a set of features and tools that make it easy to build and deploy high-performance web applications, such as automatic code splitting, server-side rendering, and static site generation.

Next.js also simplifies the setup process and provides a development environment that allows developers to focus on writing code and not on configuring the application. With Next.js, developers can create universal web applications with a great developer experience and a high level of performance.

To get started first create a new NextJS app and run it on our dev server like this −

npx create-next-app spinner-app
cd phone-input
npm start


  • First, import the CircularProgress component from the @material-ui/core library −

import { CircularProgress } from '@mui/material';
  • Next, create a state variable that will determine whether the spinner should be displayed or not −

const [isLoading, setIsLoading] = useState(false);
  • Use the state variable to control the visibility of the spinner. For example, you can add a condition in your component's render method that checks if the isLoading state is true, and if so, displays the spinner −

{isLoading && <CircularProgress />}
  • Finally, you can use the setIsLoading function to change the state of the isLoading variable. For example, you can set the state to true when a component is first rendered, and then set it to false when the data has been fetched.

useEffect(() => {
   // Fetch data here
}, []);

Note −It is important to use the isLoading state variable in a controlled way, only setting it to true when you are about to fetch data, and then setting it to false once the data has been received.

Now that we have discussed the approach let’s have a look at the final code.



import React, { useState, useEffect } from 'react'; import { CircularProgress } from '@mui/material'; const MyComponent = () => { const [isLoading, setIsLoading] = useState(false); const [data, setData] = useState([]); useEffect(() => { setIsLoading(true); // Fetch data here fetch('') .then(response => response.json()) .then(data => { setData(data); setIsLoading(false); }) .catch(error => console.log(error)); }, []); return ( <div> {isLoading ? ( <CircularProgress /> ) : ( <div> { => ( <div key={}> <h2>{item.title}</h2> <p>{item.body}</p> </div> ))} </div> )} </div> ); }; export default MyComponent;

index.js −

import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; import MyComponent from "./MyComponent"; const rootElement = document.getElementById("root"); const root = createRoot(rootElement); root.render( <StrictMode> <MyComponent /> </StrictMode> );