nextjs-progressbar
nextjs-progressbar copied to clipboard
Next 13 app dir support
Hello there, I've noticed that next 13 removed router.events
(the API that this lib uses to detect the route change)
There is a conversation going on here relevant for this topic: https://github.com/vercel/next.js/discussions/41745#discussioncomment-3986452
Anyone found a nasty workaround to get a progress bar at the top of the page on Next 13 (app directory)?
Thanks!
In chromium based browsers you might use the new native navigation api, though this doesn't work in Firefox or Safari 🤔.
useEffect(() => {
const { navigation } = window;
if (navigation) {
navigation.addEventListener("navigate", routeChangeStart);
navigation.addEventListener("navigateerror", routeChangeError);
navigation.addEventListener("navigatesuccess", routeChangeEnd);
return () => {
navigation.removeEventListener("navigate", routeChangeStart);
navigation.removeEventListener("navigateerror", routeChangeError);
navigation.removeEventListener("navigatesuccess", routeChangeEnd);
};
}
}, []);
https://developer.chrome.com/docs/web-platform/navigation-api
Would love to see this addressed, more and more people are on Next 13 by the day
Any updates on next13? is there any way to pull this off?
!bump! On production in app directory. Plz help:p
Working with this module and it has an issue with the latest version of nextjs, any assistance will be much appreciated at this point.
I couldn't find any way to implement it for appDir
, you can still use it with pages
dir in the latest version of nextjs but for appDir
, since it's still in beta so for now use loading.tsx
and if they bring back router.events
or any similar api in appDir
before the stable release, we'll add support for it
This discussion thread may be relevant:
- https://github.com/vercel/next.js/discussions/41745#discussioncomment-4208449
@jmcmullen's workaround over there (seems kind of hacky, but maybe it's a way forward in the interim until the events are exposed by Next.js in the app directory?):
I managed to get it working on all links. You can create the following client component and include it inside your root layout.tsx file
"use client";
import { useEffect } from "react";
import NProgress from "nprogress";
type PushStateInput = [
data: any,
unused: string,
url?: string | URL | null | undefined
];
export default function ProgressBar() {
const height = "2px";
const color = "#F6F01E";
const styles = (
<style>
{`
#nprogress {
pointer-events: none;
}
#nprogress .bar {
background: ${color};
position: fixed;
z-index: 99999;
top: 0;
left: 0;
width: 100%;
height: ${typeof height === `string` ? height : `${height}px`};
}
/* Fancy blur effect */
#nprogress .peg {
display: block;
position: absolute;
right: 0px;
width: 100px;
height: 100%;
box-shadow: 0 0 10px ${color}, 0 0 5px ${color};
opacity: 1.0;
-webkit-transform: rotate(3deg) translate(0px, -4px);
-ms-transform: rotate(3deg) translate(0px, -4px);
transform: rotate(3deg) translate(0px, -4px);
}
`}
</style>
);
useEffect(() => {
NProgress.configure({ showSpinner: false });
const handleAnchorClick = (event: MouseEvent) => {
const targetUrl = (event.currentTarget as HTMLAnchorElement).href;
const currentUrl = location.href;
if (targetUrl !== currentUrl) {
NProgress.start();
}
};
const handleMutation: MutationCallback = () => {
const anchorElements = document.querySelectorAll("a");
anchorElements.forEach((anchor) =>
anchor.addEventListener("click", handleAnchorClick)
);
};
const mutationObserver = new MutationObserver(handleMutation);
mutationObserver.observe(document, { childList: true, subtree: true });
window.history.pushState = new Proxy(window.history.pushState, {
apply: (target, thisArg, argArray: PushStateInput) => {
NProgress.done();
return target.apply(thisArg, argArray);
},
});
});
return styles;
}
Any updates on next13? is there any way to pull this off?
I found this npm package: https://www.npmjs.com/package/nextjs-toploader
- It perfectly works with the next js 13 in the
layout.js
for theapp
directory
Any updates on next13? is there any way to pull this off?
I found this npm package: https://www.npmjs.com/package/nextjs-toploader
- It perfectly works with the next js 13 in the
page.js
for theapp
directory
No shit
Any updates on next13? is there any way to pull this off?
I found this npm package: https://www.npmjs.com/package/nextjs-toploader
* It perfectly works with the next js 13 in the `page.js` for the `app` directory
Any updates on next13? is there any way to pull this off?
I found this npm package: https://www.npmjs.com/package/nextjs-toploader
- It perfectly works with the next js 13 in the
page.js
for theapp
directoryNo shit
does it work?
Yeah, works for me very well.
Yeah, works for me very well.
i put it in my _layout, it doesnt work
Any updates on next13? is there any way to pull this off?
I found this npm package: https://www.npmjs.com/package/nextjs-toploader
* It perfectly works with the next js 13 in the `page.js` for the `app` directory
Any updates on next13? is there any way to pull this off?
I found this npm package: https://www.npmjs.com/package/nextjs-toploader
- It perfectly works with the next js 13 in the
page.js
for theapp
directoryNo shit
does it work?
I inserted in my layout.tsx inside the body tag, it worked for me
Hey everyone, this is working for me in NextJS v13.
I have created a quick demo of this package.
Here is my package.json
file:
{
"name": "test-progress",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@types/node": "18.15.3",
"@types/react": "18.0.28",
"@types/react-dom": "18.0.11",
"eslint": "8.36.0",
"eslint-config-next": "13.2.4",
"next": "13.2.4",
"nextjs-progressbar": "^0.0.16",
"react": "18.2.0",
"react-dom": "18.2.0",
"typescript": "5.0.2"
}
}
This is pages/_app.tsx
:
import type { AppProps } from 'next/app';
import { useRouter } from 'next/router';
import NextProgressbar from 'nextjs-progressbar';
import { useEffect, useState } from 'react';
export default function App({ Component, pageProps }: AppProps) {
const [isLoading, setLoading] = useState(false);
const router = useRouter();
useEffect(() => {
// Handle route change
router.events.on('routeChangeStart', (url) => {
setLoading(true);
});
router.events.on('routeChangeError', () => {
setTimeout(() => {
setLoading(false);
}, 2000);
});
router.events.on('routeChangeComplete', () => {
setTimeout(() => {
setLoading(false);
}, 2000);
});
}, []);
return (
<>
{isLoading ? <NextProgressbar /> : null}
<Component {...pageProps} />
</>
);
}
This is pages/index.tsx
:
import Link from 'next/link'
export default function Home() {
return (
<>
Index
<Link href="/about">About</Link>
</>
)
}
This is pages/about.tsx
:
import Link from 'next/link'
function AboutPage() {
return <h1>About Page <Link href="/">Home</Link></h1>
}
export default AboutPage
Keeping this thread open for a few more days.
@apal21 this is about the app/
directory, as noted in this paragraph in the description:
Anyone found a nasty workaround to get a progress bar at the top of the page on Next 13 (app directory)?
Probably the issue title should be changed.
Any updates on next13? is there any way to pull this off?
I found this npm package: https://www.npmjs.com/package/nextjs-toploader
- It perfectly works with the next js 13 in the
layout.js
for theapp
directory
This seems a bit buggy. For me, it triggers the progress bar when I open a dropdown menu.
You can use nextjs-toploader lib which supports both /app and /pages directory. Until this starts supporting it.
import NextTopLoader from 'nextjs-toploader';
// for /app directory, put it in /layout.tsx file like this
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<NextTopLoader />
{children}
</body>
</html>
);
}
// for /pages directory, put it in /_app.tsx file like this
export default function MyApp({ Component, pageProps }) {
return (
<>
<NextTopLoader />
<Component {...pageProps} />;
</>
);
}
Not Working on nextjs 13 app directory but perfectly works on pages directory? When we get support for app directory. Waiting for it ????Would be very happy to use this package instead of loading.tsx file.
The following works (next 13.4.6, nprogress 0.2.0, react 18.2.0)
'use client';
import { useEffect } from 'react';
import NProgress from 'nprogress';
import StyledProgressBar from './styles';
type PushStateInput = [data: unknown, unused: string, url?: string | URL | null | undefined];
export default function ProgressBar() {
useEffect(() => {
NProgress.configure({ showSpinner: false });
const handleAnchorClick = (event: MouseEvent) => {
const targetUrl = (event.currentTarget as HTMLAnchorElement).href;
const currentUrl = window.location.href;
if (targetUrl !== currentUrl) {
NProgress.start();
}
};
const handleMutation: MutationCallback = () => {
const anchorElements: NodeListOf<HTMLAnchorElement> = document.querySelectorAll('a[href]');
anchorElements.forEach(anchor => anchor.addEventListener('click', handleAnchorClick));
};
const mutationObserver = new MutationObserver(handleMutation);
mutationObserver.observe(document, { childList: true, subtree: true });
window.history.pushState = new Proxy(window.history.pushState, {
apply: (target, thisArg, argArray: PushStateInput) => {
NProgress.done();
return target.apply(thisArg, argArray);
},
});
});
return <StyledProgressBar />;
}
And then in your app/layout.tsx
:
<ThemeProvider>
<ProgressBar />
{children}
</ThemeProvider>
....
I tried https://www.npmjs.com/package/nextjs-progressbar at first. I created a client component then wrapped my pages with it inside of layout.jsx file but it did not work. I tried https://www.npmjs.com/package/nextjs-toploader as suggested and it works. I am still using a client component to wrap my pages
Any updates on next13? is there any way to pull this off?
I found this npm package: https://www.npmjs.com/package/nextjs-toploader
- It perfectly works with the next js 13 in the
layout.js
for theapp
directory
Any updates on next13? is there any way to pull this off?
I found this npm package: https://www.npmjs.com/package/nextjs-toploader
- It perfectly works with the next js 13 in the
layout.js
for theapp
directory
Thanks a lot
This seems a bit buggy. For me, it triggers the progress bar when I open a dropdown menu.
Many recommend using nextjs-toploader, but has anyone actually looked at how this package is implemented? No one in their right mind would use it in a somewhat serious project because of the endless bugs and performance issues.
https://github.com/TheSGJ/nextjs-toploader
this is perfectly working on the next js v13 app router/directory
I would highly recommend all to use it
Both solutions from above work with links only and not with router.push()
. Anyone has an idea how to make it work with router.push()
as well?
Both solutions from above work with links only and not with
router.push()
. Anyone has an idea how to make it work withrouter.push()
as well?
Yeah I wish it would work for router.push()
/ router.replace()
<Link href={'/theway(static)'} prefetch={false} id='ID123' className='hidden'></Link>
document.getElementById('ID123')?.click()` // or ref and then click
This may work for static path.
https://github.com/TheSGJ/nextjs-toploader It's working but has a issue, it's keeps loading and never finish or completes..
https://github.com/TheSGJ/nextjs-toploader/issues/56
https://github.com/TheSGJ/nextjs-toploader It's working but has a issue, it's keeps loading and never finish or completes..
Issue is fixed in NextJs v14.0.4