Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Next 13 app dir support #86

Open
Fedeorlandau opened this issue Nov 4, 2022 · 27 comments
Open

Next 13 app dir support #86

Fedeorlandau opened this issue Nov 4, 2022 · 27 comments

Comments

@Fedeorlandau
Copy link

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: vercel/next.js#41745 (comment)

Anyone found a nasty workaround to get a progress bar at the top of the page on Next 13 (app directory)?

Thanks!

@HaNdTriX
Copy link

HaNdTriX commented Nov 7, 2022

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

@AlanMorel
Copy link

Would love to see this addressed, more and more people are on Next 13 by the day

@Pyakz
Copy link

Pyakz commented Feb 4, 2023

Any updates on next13? is there any way to pull this off?

@jimapl
Copy link

jimapl commented Feb 17, 2023

!bump!
On production in app directory. Plz help:p

@mairura
Copy link

mairura commented Feb 17, 2023

Working with this module and it has an issue with the latest version of nextjs, any assistance will be much appreciated at this point.

@imranbarbhuiya
Copy link
Collaborator

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

@karlhorky
Copy link

karlhorky commented Feb 28, 2023

This discussion thread may be relevant:

@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;
}

@anamiikajha
Copy link

anamiikajha commented Mar 7, 2023

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 the app directory

@jimapl
Copy link

jimapl commented Mar 7, 2023

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

No shit

@Pyakz
Copy link

Pyakz commented Mar 7, 2023

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 the app directory

No shit

does it work?

@anamiikajha
Copy link

Yeah, works for me very well.

@Pyakz
Copy link

Pyakz commented Mar 7, 2023

Yeah, works for me very well.

i put it in my _layout, it doesnt work

@EdsonLucasbd
Copy link

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 the app directory

No shit

does it work?

I inserted in my layout.tsx inside the body tag, it worked for me

@apal21
Copy link
Owner

apal21 commented Mar 19, 2023

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.

@karlhorky
Copy link

@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.

@codinginflow
Copy link

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 the app directory

This seems a bit buggy. For me, it triggers the progress bar when I open a dropdown menu.

@SRX9
Copy link

SRX9 commented May 22, 2023

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} />;
    </>
  );
}

@ChetSocio
Copy link

ChetSocio commented May 26, 2023

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.

@pimmee
Copy link

pimmee commented Jun 20, 2023

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>

              ....

@imranbarbhuiya imranbarbhuiya changed the title Next 13 support Next 13 app dir support Jun 27, 2023
@lul-g
Copy link

lul-g commented Jul 29, 2023

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 the app directory

@vikramsamak
Copy link

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 the app directory

Thanks a lot

@monolithed
Copy link

monolithed commented Aug 18, 2023

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.

@Darpan-favfly
Copy link

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

@IlirEdis
Copy link

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?

@Bogd1y
Copy link

Bogd1y commented Nov 15, 2023

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?

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.

@jigsaxis
Copy link

jigsaxis commented Dec 1, 2023

https://github.com/TheSGJ/nextjs-toploader It's working but has a issue, it's keeps loading and never finish or completes..

TheSGJ/nextjs-toploader#56

@jigsaxis
Copy link

https://github.com/TheSGJ/nextjs-toploader It's working but has a issue, it's keeps loading and never finish or completes..

TheSGJ/nextjs-toploader#56

Issue is fixed in NextJs v14.0.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests