How To Handle Loading Between Page Changes in NextJS?
Last Updated : 27 May, 2024
To experience smooth transitions between the pages of your Next.js application, you can include a loading indicator that shows the progress of the page being loaded. This can be done by creating a custom spinner component and using it during page transitions.
In this article, we will create a custom spinner component and display it between page transitions in a Next.js application.
Approach to Handle Loading Between Page Changes in Next.js
- Create the Spinner Component: Create a new file named loadingIndicator.js inside the pages. This is a simple component we bring the life to this component with our CSS.
- Style the Loading Indicator: Using CSS, we will style the above component that purely transforms itself into a spinner.
- Create another page to navigate and test our loading spinner while transitioning between pages.
- Integrating the Loading Indicator: To integrate the loading indicator, we will modify the _app.js file. This file acts as the top-level component in your Next.js app and is ideal for managing global states like a loading indicator.
- Modify _app.js: Open the pages/_app.js file and update it as follows:
- A delay of 2000 milliseconds is added before hiding the loading indicator. This ensures that the indicator is visible for a short period, even for fast transitions.
Steps to Create NextJS App
Step 1: Create a Next.Js project with the following commands in your desired location with the desired project name.
npx create-next-app demoapp
cd demoapp
Step 2: Start the Development Server:
npm run dev
Step 3: Create the following files required to execute our example that shows how to handle loading between pages.
pages/loadingIndicator.js
pages/LoadingIndicator.module.css
pages/page2.js
Project structure
demoapp structureExample: Below is an example to handle loading between pafe changes in Next.js.
CSS /* pages/LoadingIndicator.module.css */ .loadingindicator { position: fixed; top: 0; left: 0; width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; background: rgba(255, 255, 255, 0.8); z-index: 9999; font-size: 20px; color: #000; } .spinner { border: 4px solid rgba(0, 0, 0, 0.1); border-left-color: #000; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin-right: 10px; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
JavaScript // pages/LoadingIndicator.js import React from "react"; //Create a CSS file for styling import style from "./LoadingIndicator.module.css"; const LoadingIndicator = () => ( <div className={style.loadingindicator}> <div className={style.spinner}></div> Loading... </div> ); export default LoadingIndicator;
JavaScript // pages/page2.js import React from "react"; function page2() { return ( <div style={{ height: "100vh", fontSize: "50px", backgroundColor: "grey" }}> <h2>this is page 2</h2> </div> ); } export default page2;
JavaScript // pages/_app.js import "@/styles/globals.css"; import Router from "next/router"; import { useState, useEffect } from "react"; import LoadingIndicator from "./loadingIndicator"; function MyApp({ Component, pageProps }) { const [loading, setLoading] = useState(false); useEffect(() => { const handleStart = () => setLoading(true); const handleComplete = () => { // Adding a delay before setting loading to false setTimeout(() => setLoading(false), 2000); // 500ms delay }; 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 && <LoadingIndicator />} {!loading && <Component {...pageProps} />} </> ); } export default MyApp;
JavaScript // pages/index.js import { useRouter } from "next/router"; import React from "react"; function Index() { const router = useRouter(); return ( <div style={{ fontSize: "50px" }}> <h2>This is page 1</h2> <input type="button" value="Click me" style={{ fontSize: "30px" }} onClick={() => { router.push("/page2"); }} /> </div> ); } export default Index;
Output:
Best Practices and Tips
- Consistent User Experience: Ensure that the loading indicator is consistently shown during all page transitions. This provides a uniform user experience across your app.
- Performance Considerations: Be mindful of the performance impact. While the loading indicator enhances user experience, it should not significantly slow down transitions.
- Adjustable Delay: The delay time before hiding the loading indicator can be adjusted based on your app's needs. Too short a delay may make the indicator flash briefly, while too long a delay might make transitions feel slow.
Alternative Approach Using External Packages
1. Install nprogress:
npm install nprogress
2. Verify dependencies.
"dependencies": {
"next": "14.2.3",
"nprogress": "^0.2.0",
"react": "^18",
"react-dom": "^18",
"web3": "^4.8.0"
}
3. Set Up nprogress in _app.js:
JavaScript //pages/_app.js import "nprogress/nprogress.css"; import NProgress from "nprogress"; import Router from "next/router"; import { useEffect } from "react"; import "../styles/globals.css"; function MyApp({ Component, pageProps }) { useEffect(() => { const handleStart = () => NProgress.start(); const handleComplete = () => NProgress.done(); 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 <Component {...pageProps} />; } export default MyApp;
Output:
Conclusion:
Displaying a loading indicator during page transitions in Next.js significantly enhances user experience by providing visual feedback. Whether you implement a custom solution or use an external package like nprogress, ensure that your implementation is smooth and does not negatively impact performance. By following this guide, you can create a more polished and user-friendly application.
Similar Reads
How to Share Data Between Pages in Next.js?
Sharing data between pages in Next.js can be crucial for maintaining state and passing information efficiently. You can achieve this with the help of URL parameters. In this article, we will learn about how to share data between pages in next.js Approach to Share Data Between PagesUse the Link compo
2 min read
How to add Skeleton Loading in NextJS ?
Skeleton Loading in Next.js provides a placeholder UI while content is loading, improving perceived performance and user experience. It visually represents loading elements, ensuring a smoother, more engaging application. ApproachTo add skeleton loading in nextjs application we are going to use the
2 min read
Linking between pages in Next.js
In this article, we are going to see how we can link one page to another in Next.js. Follow the below steps to set up the linking between pages in the Next.js application: To create a new NextJs App run the below command in your terminal: npx create-next-app GFGAfter creating your project folder (i.
3 min read
Navigate Between Pages in NextJS
Navigating between pages in Next.js is smooth and optimized for performance, with the help of its built-in routing capabilities. The framework utilizes client-side navigation and dynamic routing to ensure fast, smooth transitions and an enhanced user experience. Prerequisites:Node.js and NPMReactJSN
3 min read
How To Add Navbar To All Pages In NextJS ?
A navbar is a common UI element used to navigate between different sections or pages of a website. Adding a navbar to all pages ensures consistent navigation across the site. This article will explore how we can add a navbar to all pages In NextJS. Output Preview: Prerequisites:NextJSReactJSReact Ho
3 min read
How To Add Styling To An Active Link In NextJS?
Styling active links is important for enhancing user navigation by providing visual feedback on the current page or section. In Next.js, you can achieve this by using the Link component from next/link and applying styles conditionally based on the active route. In this article, we will learn about h
3 min read
How to add Loading Quotes in Next.js ?
In this article, we are going to learn how we can add loading quotes in NextJs. NextJS is a React-based framework. It has the power to Develop beautiful Web applications for different platforms like Windows, Linux, and mac. The linking of dynamic paths helps in rendering your NextJS components condi
2 min read
How to create a Custom Error Page in Next.js ?
Creating a custom error page in Next.js allows you to provide a better user experience by customizing the appearance and messaging of error pages like 404 and 500. In this post we are going to create a custom error page or a custom 404 page in a Next JS website. What is a custom error page?The 404 p
2 min read
How to Handle a Post Request in Next.js?
NextJS is a React framework that is used to build full-stack web applications. It is used both for front-end as well as back-end. It comes with a powerful set of features to simplify the development of React applications. In this article, we will learn about How to handle a post request in NextJS. A
2 min read
How to Handle Different Environments in a Next.js?
Environment variables in NextJS are fundamental settings or values that can change based on the application's deployment environment. They are crucial for separating sensitive information, such as API keys, database credentials, or configuration details, from the application codebase. In a NextJS pr
4 min read