TheSGJ / nextjs-toploader

A Next.js Top Loading Bar component made using nprogress, works with Next.js 14 , Next.js 13 and React.
https://www.npmjs.com/package/nextjs-toploader
MIT License
867 stars 50 forks source link

NextTopLoader stopped working on Nextjs 14.0.3 #56

Open ajsystem opened 1 year ago

ajsystem commented 1 year ago

Hello, just to report that on a project with the last Nextjs 14.0.3, the toploader keeps loading and never finish or completes.

But there aren't errors on console server/client.

As a workaround to get it working install 14.0.2

rrojan commented 1 year ago

Same here. the progress bar is stuck at the end and never finishes loading since NextJS 14.0.3.

It also looks less snappy, if that makes sense. At the time where it previously completed loading, it now goes to around at 60-70% progress and slowly crawls its way to the end, but doesn't stop loading.

SuhelMakkad commented 1 year ago

+1

jonathanwilke commented 1 year ago

Same problem for me. Downgrading to 14.0.2 fixed it.

TheSGJ commented 1 year ago

Next js 14.0.3 added experimental support for history.pushState and history.replaceState. That's why it's messing with history.pushState() method in the code. Here's the pr which introduced it: vercel/next.js/pull/58335

putramaghfirah commented 1 year ago

same problem.

croofec commented 1 year ago

+1

sengawasenga commented 1 year ago

I got the same problem, how can we solve it ?

omarqra commented 1 year ago

+1

preeti-192 commented 1 year ago
import type { Metadata } from 'next';
import './globals.css';
import { ReactNode } from 'react';
import NextTopLoader from 'nextjs-toploader';
import AppWrapper from './AppWrapper';

export default function RootLayout({
  children,
}: Readonly<{
  children: ReactNode;
}>) {
  return (
    <html lang="en" className="antialiased">
      <body>
        <NextTopLoader
          color="hsl(var(--secondary-light))"
          initialPosition={0.08}
          crawlSpeed={200}
          height={3}
          crawl
          showSpinner
          easing="ease"
          speed={200}
          shadow="0 0 10px hsl(var(--secondary)),0 0 5px hsl(var(--secondary-light))"
          template='<div class="bar" role="bar"><div class="peg"></div></div> 
  <div class="spinner" style="top: 65px" role="spinner"><div class="spinner-icon"></div></div>'
          zIndex={999999}
        />
        <main>
          <AppWrapper>{children}</AppWrapper>
        </main>
      </body>
    </html>
  );
}
PedroL22 commented 1 year ago

same here

besufkadmenji commented 1 year ago

Possible fix: run NProgress.done() inside your top level client component, this will cleanup any stuck loader

import * as NProgress from "nprogress";

useEffect(() => {
    NProgress.done();
}, [pathname, router]);
Jings commented 1 year ago

Possible fix: run NProgress.done() inside your top level client component, this will cleanup any stuck loader

import * as NProgress from "nprogress";

useEffect(() => {
    NProgress.done();
}, [pathname, router]);

This works for now. Hopefully the proper fix will come soon :)

joshke commented 1 year ago

+1

Super-Kenil commented 1 year ago

+1

monir6163 commented 1 year ago

Possible fix: run NProgress.done() inside your top level client component, this will cleanup any stuck loader

import * as NProgress from "nprogress";

useEffect(() => {
    NProgress.done();
}, [pathname, router]);

why root layout client-side rendering? I hope it is not good practiche

Jings commented 1 year ago

Possible fix: run NProgress.done() inside your top level client component, this will cleanup any stuck loader

import * as NProgress from "nprogress";

useEffect(() => {
    NProgress.done();
}, [pathname, router]);

why root layout client-side rendering? I hope it is not good practiche

@besufkadmenji is only talking about your top most client component not root layout client side rendering. If this is your root layout, fine. For me it is not but instead two or three pages that are the top most client components.

vnevermore commented 1 year ago

same problem here

gokulkrishh commented 1 year ago

Possible fix: run NProgress.done() inside your top level client component, this will cleanup any stuck loader

import * as NProgress from "nprogress";

useEffect(() => {
    NProgress.done();
}, [pathname, router]);

Yep this worked for me. But we need proper fix. Thanks for suggesting.

NestedGateway commented 1 year ago

Also facing problem with nextjs 14. I am still using it because there is no such alternative to it. All other all manual.

gustaveWPM commented 1 year ago

Possible fix: run NProgress.done() inside your top level client component, this will cleanup any stuck loader

import * as NProgress from "nprogress";

useEffect(() => {
    NProgress.done();
}, [pathname, router]);

Thank you so much! I added it at the top of my <Providers> component.

My root layout looks like this:

<html lang={language} dir={dir}>
  <body>
    <div>
      <Providers locale={language}>
        <NextTopLoader {...} />
        {children}
// ...

So that's a really good workaround, imo.

andrewmumblebee commented 12 months ago

Potentially will be fixed by https://github.com/vercel/next.js/pull/58861

nunesunil commented 12 months ago

Fixed by https://github.com/vercel/next.js/pull/58861 and released in v14.0.4-canary.37.

Super-Kenil commented 11 months ago

@ajsystem , I checked the latest Nextjs v14.0.4. and nextjs-toploader works fine in that version. I think this issues should be closed now

mamlzy commented 11 months ago

@ajsystem , I checked the latest Nextjs v14.0.4. and nextjs-toploader works fine in that version. I think this issues should be closed now

let see what other people opinions first, just to make sure before it's closed😉

gokulkrishh commented 11 months ago

@ImamAlfariziSyahputra @Super-Kenil Yep issue is fixed in v14.0.4 for my app expense.fyi

Super-Kenil commented 11 months ago

@ImamAlfariziSyahputra . I had already tested it in 3 of my projects, then I commented here. @gokulkrishh thanks for confirming

gustaveWPM commented 11 months ago

Fixed!

bschwartz10 commented 10 months ago

Still experiencing the stuck loader when its 99% done. This is happening specifically when using the custom useRouter solution from this issue: https://github.com/TheSGJ/nextjs-toploader/issues/10#issuecomment-1809417610

"next": "^14.0.4"
"nextjs-toploader": "^1.6.4"
"nprogress": "^0.2.0"
B33fb0n3 commented 10 months ago

Still not working :(

"next": "14.1.0",
"nextjs-toploader": "^1.6.4",
sho-pb commented 10 months ago

my solutions

// NextTopLoader.tsx
'use client';

import Loader from 'nextjs-toploader';
import { usePathname } from 'next/navigation';

const NextTopLoader = () => {
  const pathname = usePathname();

  useEffect(() => {
    NProgress.done();
  }, [pathname]);

  return (
    <Loader />
  )
}
// useRouter.ts
import { NavigateOptions } from 'next/dist/shared/lib/app-router-context.shared-runtime';
import { useRouter as useNextRouter, usePathname } from 'next/navigation';
import { useCallback } from 'react';
import NProgress from 'nprogress';

export const useRouter = () => {
  const router = useNextRouter();
  const pathname = usePathname();

  const replace = useCallback(
    (href: string, options?: NavigateOptions) => {
      href !== pathname && NProgress.start();
      router.replace(href, options);
    },
    [router, pathname],
  );

  const push = useCallback(
    (href: string, options?: NavigateOptions) => {
      href !== pathname && NProgress.start();
      router.push(href, options);
    },
    [router, pathname],
  );

  return {
    ...router,
    replace,
    push,
  };
};
Super-Kenil commented 9 months ago

@B33fb0n3

Still not working :(

"next": "14.1.0",
"nextjs-toploader": "^1.6.4",

I am using nextjs-toploader, With same version you're using, Both Next and nextjs-toploader and it seems to be working perfectly on my end.

For fixing it, make sure you are not using it multiple times unnecessarily in your App. If it doesn't get fixed, please create a Reproduction so that we could take a look at it

moon2850088 commented 8 months ago

my solutions

// NextTopLoader.tsx
'use client';

import Loader from 'nextjs-toploader';
import { usePathname } from 'next/navigation';

const NextTopLoader = () => {
  const pathname = usePathname();

  useEffect(() => {
    NProgress.done();
  }, [pathname]);

  return (
    <Loader />
  )
}
// useRouter.ts
import { NavigateOptions } from 'next/dist/shared/lib/app-router-context.shared-runtime';
import { useRouter as useNextRouter, usePathname } from 'next/navigation';
import { useCallback } from 'react';
import NProgress from 'nprogress';

export const useRouter = () => {
  const router = useNextRouter();
  const pathname = usePathname();

  const replace = useCallback(
    (href: string, options?: NavigateOptions) => {
      href !== pathname && NProgress.start();
      router.replace(href, options);
    },
    [router, pathname],
  );

  const push = useCallback(
    (href: string, options?: NavigateOptions) => {
      href !== pathname && NProgress.start();
      router.push(href, options);
    },
    [router, pathname],
  );

  return {
    ...router,
    replace,
    push,
  };
};

It works for me. Thanks for your solution !

rohankm commented 8 months ago

my solutions

// NextTopLoader.tsx
'use client';

import Loader from 'nextjs-toploader';
import { usePathname } from 'next/navigation';

const NextTopLoader = () => {
  const pathname = usePathname();

  useEffect(() => {
    NProgress.done();
  }, [pathname]);

  return (
    <Loader />
  )
}
// useRouter.ts
import { NavigateOptions } from 'next/dist/shared/lib/app-router-context.shared-runtime';
import { useRouter as useNextRouter, usePathname } from 'next/navigation';
import { useCallback } from 'react';
import NProgress from 'nprogress';

export const useRouter = () => {
  const router = useNextRouter();
  const pathname = usePathname();

  const replace = useCallback(
    (href: string, options?: NavigateOptions) => {
      href !== pathname && NProgress.start();
      router.replace(href, options);
    },
    [router, pathname],
  );

  const push = useCallback(
    (href: string, options?: NavigateOptions) => {
      href !== pathname && NProgress.start();
      router.push(href, options);
    },
    [router, pathname],
  );

  return {
    ...router,
    replace,
    push,
  };
};

this works for the latest nextjs

Kamleshpaul commented 6 months ago

my solutions

// NextTopLoader.tsx
'use client';

import Loader from 'nextjs-toploader';
import { usePathname } from 'next/navigation';

const NextTopLoader = () => {
  const pathname = usePathname();

  useEffect(() => {
    NProgress.done();
  }, [pathname]);

  return (
    <Loader />
  )
}
// useRouter.ts
import { NavigateOptions } from 'next/dist/shared/lib/app-router-context.shared-runtime';
import { useRouter as useNextRouter, usePathname } from 'next/navigation';
import { useCallback } from 'react';
import NProgress from 'nprogress';

export const useRouter = () => {
  const router = useNextRouter();
  const pathname = usePathname();

  const replace = useCallback(
    (href: string, options?: NavigateOptions) => {
      href !== pathname && NProgress.start();
      router.replace(href, options);
    },
    [router, pathname],
  );

  const push = useCallback(
    (href: string, options?: NavigateOptions) => {
      href !== pathname && NProgress.start();
      router.push(href, options);
    },
    [router, pathname],
  );

  return {
    ...router,
    replace,
    push,
  };
};

this works

Himture commented 3 months ago

Solution given by @sho-pb is perfect and works well and you can also do all the customization to the loader in the NextTopLoader.tsx file by adding the props there in the return. Kudos!

Emiliano-Bucci commented 2 weeks ago

@sho-pb Hi! Is your solution also working with the browser back button? :)