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

Compatibility with useRouter #10

Open
PixeledCode opened this issue May 1, 2023 · 21 comments
Open

Compatibility with useRouter #10

PixeledCode opened this issue May 1, 2023 · 21 comments
Labels
enhancement New feature or request

Comments

@PixeledCode
Copy link

PixeledCode commented May 1, 2023

Great Library. Thanks for your work.
So far it works great for Link components but for useRouter, it doesn't seem to work at all. Is there some workaround it?

Edit: After going through multiple comments here, I have settled on this approach https://github.com/CivicDataLab/opub-mono/blob/main/apps/www/lib/navigation.tsx

  • I can start and stop the progress bar on demand.
  • Also using zustand to keep a meta state globally for when page transitioning is happening
@Aspedm
Copy link

Aspedm commented May 3, 2023

+1, it will be great. But I think it's impossible now, with current app dir api. I'll be glad if I'm wrong.

@zbeyens
Copy link

zbeyens commented May 8, 2023

Here is my workaround:

export const usePRouter = () => {
  const router = useRouter();

  const { push } = router;

  router.push = (href, options) => {
    NProgress.start();
    push(href, options);
  };

  return router;
};

// add this to a top level component
const pathname = usePathname();
const searchParams = useSearchParams();

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

@PixeledCode
Copy link
Author

Here is my workaround:

export const usePRouter = () => {
  const router = useRouter();

  const { push } = router;

  router.push = (href, options) => {
    NProgress.start();
    push(href, options);
  };

  return router;
};

// add this to a top level component
const pathname = usePathname();
const searchParams = useSearchParams();

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

are you using this library or the nprogress ?
where is that NProgress coming from?

@zbeyens
Copy link

zbeyens commented May 10, 2023

@PixeledCode Forgot to mention I've forked that library

@PixeledCode
Copy link
Author

@PixeledCode Forgot to mention I've forked that library

is your code open? can you share it?

@zbeyens
Copy link

zbeyens commented May 10, 2023

@PixeledCode Nothing different than this repo. You just need to import NProgress to start/stop anywhere you want.

import * as NProgress from 'nprogress';

@TheSGJ TheSGJ added the enhancement New feature or request label May 16, 2023
@Abesoddy
Copy link

It would be great to have this feature! Thank you for your work! :)

@PixeledCode
Copy link
Author

@PixeledCode Nothing different than this repo. You just need to import NProgress to start/stop anywhere you want.

import * as NProgress from 'nprogress';

Thanks for this, this approach worked.
I am getting this warning, Entire page /[locale]/dashboard/dataset/new deopted into client-side rendering. and since we are using useSearchParams on top level, I guess this warning will stay, right?

@Darren120
Copy link

import * as NProgress from 'nprogress';

Do you have a workaround with router.refresh() support? most mutations are now just calling refresh to refetch data.

@mrsafalpiya
Copy link

@PixeledCode Nothing different than this repo. You just need to import NProgress to start/stop anywhere you want.

import * as NProgress from 'nprogress';

Thanks for this, this approach worked. I am getting this warning, Entire page /[locale]/dashboard/dataset/new deopted into client-side rendering. and since we are using useSearchParams on top level, I guess this warning will stay, right?

This can be fixed by wrapping around the component by react suspense.

<Suspense fallback={null}><NProgressTop /></Suspense>

@uixmat
Copy link

uixmat commented Jun 22, 2023

Just put your useRouter in a function and include NProgress.start(); as @zbeyens mentioned.

Add:

import * as NProgress from "nprogress";
import { useRouter } from "next/navigation";

Example usage:

const router = useRouter();
const handlePush = () => {
    NProgress.start();
    router.push("/some-page");
};

nextjs-toploader uses NProgress under the hud.

@dan-pugsley
Copy link

This progress bar package handles Next 13, both <Link> and router.push() 👍.

You only have to modify your useRouter imports to import { useRouter } from 'next-nprogress-bar'.

Works well!

@nodegin
Copy link

nodegin commented Sep 20, 2023

@dan-pugsley awesome!

@hongaar
Copy link

hongaar commented Nov 14, 2023

#10 (comment) works like a charm, here's a TypeScript version I'm using:

// useRouter.ts

import { useRouter as useBaseRouter } from "next/navigation";
import NProgress from "nprogress";

export function useRouter() {
  const router = useBaseRouter();

  const { push } = router;

  router.push = async (...args: Parameters<typeof push>) => {
    NProgress.start();
    return push(...args);
  };

  return router;
}

@lucas-barake
Copy link

If you're using the next/router pages router, this might be of help:

import { useRouter } from "next/router";
import NProgress from "nprogress";

export function useCustomRouter(): ReturnType<typeof useRouter> {
  const router = useRouter();

  const originalPush = router.push;

  router.push = (...args: Parameters<typeof router.push>): ReturnType<typeof originalPush> => {
    NProgress.start();
    return originalPush(...args);
  };

  return router;
}

@rodrigocipriani
Copy link

#10 (comment) works like a charm, here's a TypeScript version I'm using:

// useRouter.ts

import { useRouter as useBaseRouter } from "next/navigation";
import NProgress from "nprogress";

export function useRouter() {
  const router = useBaseRouter();

  const { push } = router;

  router.push = async (...args: Parameters<typeof push>) => {
    NProgress.start();
    return push(...args);
  };

  return router;
}

Nice solution, but for me it starts loading and never ends

@hongaar
Copy link

hongaar commented Feb 5, 2024

Nice solution, but for me it starts loading and never ends

@rodrigocipriani You will probably need to add some code to make the toploader stop spinning, see:
#10 (comment)

@LuisanSuarez
Copy link

LuisanSuarez commented Apr 6, 2024

This is not a good solution.

This progress bar package handles Next 13, both <Link> and router.push() 👍.

You only have to modify your useRouter imports to import { useRouter } from 'next-nprogress-bar'.

Works well!

to use this library with Next 13+, you must turn your RootLayout into a client component with 'use client'. this turns your entire app into a client-rendered app, see the docs.

if your server component do any db fetching or use .env vars that are meant to be private (i.e. not prefixed with NEXT_PUBLIC_), then they will break. you won't be able to directly run server-side database queries on a client environment, and your .env vars will be undefined.

EDIT: fixed broken link to Next docs

@PixeledCode
Copy link
Author

This is not a good solution.

This progress bar package handles Next 13, both <Link> and router.push() 👍.
You only have to modify your useRouter imports to import { useRouter } from 'next-nprogress-bar'.
Works well!

to use this library with Next 13+, you must turn your RootLayout into a client component with 'use client'. this turns your entire app into a client-rendered app, see the docs.

if your server component do any db fetching or use .env vars that are meant to be private (i.e. not prefixed with NEXT_PUBLIC_), then they will break. you won't be able to directly run server-side database queries on a client environment, and your .env vars will be undefined.

So you have to treat it like any other provider wrapper. Usually you will create a separate Provider component, add all of the components like this and then wrap layout with it. It's a pretty common pattern

@LuisanSuarez
Copy link

This is not a good solution.
...
if your server component do any db fetching or use .env vars that are meant to be private (i.e. not prefixed with NEXT_PUBLIC_), then they will break. you won't be able to directly run server-side database queries on a client environment, and your .env vars will be undefined.

So you have to treat it like any other provider wrapper. Usually you will create a separate Provider component, add all of the components like this and then wrap layout with it. It's a pretty common pattern

The Provider pattern is fine too, but you're making a 'use-client' component a parent of all of your app. This turns your entire app into part of the client bundle, and none of it will be server rendered. If you don't care about server rendering it's not an issue. If you do however you can't use next-nprogress-bar.

@tomcru
Copy link

tomcru commented May 15, 2024

You can do this in Holy Loader ↗

'use client';

import { startHolyLoader } from 'holy-loader';

startHolyLoader();
router.push('/your-page')

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

No branches or pull requests