-
-
Notifications
You must be signed in to change notification settings - Fork 55
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
Comments
+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. |
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 ? |
@PixeledCode Forgot to mention I've forked that library |
is your code open? can you share it? |
@PixeledCode Nothing different than this repo. You just need to import import * as NProgress from 'nprogress'; |
It would be great to have this feature! Thank you for your work! :) |
Thanks for this, this approach worked. |
Do you have a workaround with router.refresh() support? most mutations are now just calling refresh to refetch data. |
This can be fixed by wrapping around the component by react suspense.
|
Just put your Add:import * as NProgress from "nprogress";
import { useRouter } from "next/navigation"; Example usage:const router = useRouter();
const handlePush = () => {
NProgress.start();
router.push("/some-page");
};
|
This progress bar package handles Next 13, both You only have to modify your Works well! |
@dan-pugsley awesome! |
#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;
} |
If you're using the 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;
} |
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: |
This is not a good solution.
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 |
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. |
This approach worked for me and i didn't had to use this useEffect in my layout:
The custom hook:
|
@PixeledCode I was getting a maximum call stack exception with your solution when quickly changing pages. I come up with this in the end
|
This really does the job. |
Use this method to you component . It works 100% . 'use client';
import React, { useCallback, useState, useRef } from 'react'
import Link from 'next/link'
type UseHiddenLinkReturn = {
navigate: (href: string) => void
isNavigating: boolean
HiddenLink: React.FC
}
export const useLinkNavigation = (): UseHiddenLinkReturn => {
const [href, setHref] = useState<string | null>(null)
const [isNavigating, setIsNavigating] = useState(false)
const linkRef = useRef<HTMLAnchorElement>(null)
const navigate = useCallback((newHref: string) => {
setHref(newHref)
setIsNavigating(true)
setTimeout(() => {
linkRef.current?.click()
}, 0)
}, [])
const HiddenLink: React.FC = () => (
<Link
href={href || ''}
ref={linkRef}
tabIndex={-1}
aria-hidden="true"
onClick={() => setIsNavigating(false)}
className="sr-only"
>
Navigating to {href}
</Link>
)
return { navigate, isNavigating, HiddenLink }
}
// Example usage of the hook
export default function NavigationExample() {
const { navigate, isNavigating, HiddenLink } = useHiddenLink()
return (
<div className="p-4">
<h1 className="text-2xl font-bold mb-4">Hidden Link Navigation Example</h1>
<button
onClick={() => navigate('/dashboard')}
className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600 transition-colors"
disabled={isNavigating}
>
{isNavigating ? 'Navigating...' : 'Go to Dashboard'}
</button>
<div className="sr-only" aria-live="polite">
{isNavigating && 'Navigating to dashboard...'}
</div>
<HiddenLink />
</div>
)
} |
Great Library. Thanks for your work.
So far it works great for
Link
components but foruseRouter
, 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
The text was updated successfully, but these errors were encountered: