The problem #
Nextjs renders the initial page on the server side and the subsequent page on the client. Because of that while navigating using Next Link
the browser does not show loading progress. This leads to giving the user the perception that nothing happened or the page is broken.
The solution #
To fix that a custom progress bar can be shown.
1. Install nprogress #
npm i -S nprogress
if using typescript also do npm i -D @types/nprogress
2. Change _app.js
file to call nprogress on router events #
// _app.jsx or _app.tsx
// add import
import nProgress from "nprogress";
import { Router } from "next/router";
import "nprogress/nprogress.css"
Router.events.on("routeChangeStart", nProgress.start);
Router.events.on("routeChangeError", nProgress.done);
Router.events.on("routeChangeComplete", nProgress.done);
// end
function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
}
export default MyApp;
3. (Optional) Customize progress bar #
By default nprogress show a blue progress bar on top of page. That may not match the Website look and feel. To customize
- create a new file named
nprogress.css
in styles directory. - Paste the following code in that file and change
--primary-color: #ff0000
to whichever color you want
/* Make clicks pass-through */
#nprogress {
--primary-color: #ff0000;
pointer-events: none;
}
#nprogress .bar {
background: var(--primary-color);
position: fixed;
z-index: 1031;
top: 0;
left: 0;
width: 100%;
height: 2px;
}
/* Fancy blur effect */
#nprogress .peg {
display: block;
position: absolute;
right: 0px;
width: 100px;
height: 100%;
box-shadow: 0 0 10px var(--primary-color), 0 0 5px var(--primary-color);
opacity: 1.0;
-webkit-transform: rotate(3deg) translate(0px, -4px);
-ms-transform: rotate(3deg) translate(0px, -4px);
transform: rotate(3deg) translate(0px, -4px);
}
/* Remove these to get rid of the spinner */
#nprogress .spinner {
display: block;
position: fixed;
z-index: 1031;
top: 15px;
right: 15px;
}
#nprogress .spinner-icon {
width: 18px;
height: 18px;
box-sizing: border-box;
border: solid 2px transparent;
border-top-color: var(--primary-color);
border-left-color: var(--primary-color);
border-radius: 50%;
-webkit-animation: nprogress-spinner 400ms linear infinite;
animation: nprogress-spinner 400ms linear infinite;
}
.nprogress-custom-parent {
overflow: hidden;
position: relative;
}
.nprogress-custom-parent #nprogress .spinner,
.nprogress-custom-parent #nprogress .bar {
position: absolute;
}
@-webkit-keyframes nprogress-spinner {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
@keyframes nprogress-spinner {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
- change the import to
import "/styles/nprogress.css"
Since you've made it this far, sharing this article on your favorite social media network would be highly appreciated ! For feedback, please ping me on Twitter.
Published