[Docs]: Example of defining own useRouter hook #1447
-
Link to pageNo response Describe the problemHi Jan! I would like to define my own useRouter hook. The reason is that I have to add additional functionality to the hook and return the next-intl's useRouter function at the end. An example (the additional functionality is import { useCallback, useEffect } from 'react';
import { createLocalizedPathnamesNavigation } from 'next-intl/navigation';
import {
AppRouterInstance,
NavigateOptions,
} from 'next/dist/shared/lib/app-router-context.shared-runtime';
import * as NProgress from 'nprogress';
import { locales, pathnames, localePrefix } from './i18n-config';
export const {
Link,
redirect,
usePathname,
useRouter: useIntlRouter,
} = createLocalizedPathnamesNavigation({
locales,
pathnames,
localePrefix,
});
export const useRouter = (): AppRouterInstance => {
const router = useIntlRouter();
const pathname = usePathname();
useEffect(() => {
NProgress.done();
}, [pathname]);
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,
};
}; But there is a problem--the I know of a similar case--the exported Link. You made an example of that in this repo and so it was quite clear how to implement that in my own component: 'use client';
import { ComponentProps } from 'react';
import { cn } from '@/utils/utils';
import { Link } from '@/i18n-navigation';
import type { pathnames } from '@/i18n-config';
interface Props {
// href is required but it is not defined here but below using ComponentProps<typeof Link<Pathname>>
children: React.ReactNode;
className?: string;
type?: 'clean' | 'border';
onClick?: () => void;
}
export const InternalLink = <Pathname extends keyof typeof pathnames>({
children,
className,
href,
type,
onClick,
}: Props & ComponentProps<typeof Link<Pathname>>) => {
return (
<Link
href={href}
className={cn(type === 'border' ? 'border-b border-brand-pink py-0.5' : '', className)}
onClick={onClick}
>
{children}
</Link>
);
}; Thank you! |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
If you upgrade to You should be able to call I'll move this to a discussion since it seems to be more of a usage question, hope that's ok! |
Beta Was this translation helpful? Give feedback.
-
Great, that worked! Thanks a lot @amannn for such a quick response. I updated all my code based on the latest 'use client';
import { useCallback, useEffect } from 'react';
import * as NProgress from 'nprogress';
import { useIntlRouter, usePathname } from '@/i18n/routing';
export const useRouter = () => {
const router = useIntlRouter();
const pathname = usePathname();
useEffect(() => {
NProgress.done();
}, [pathname]);
const replace = useCallback(
(...args: Parameters<typeof router.replace>) => {
const [href] = args;
if (href !== pathname) {
NProgress.start();
}
router.replace(...args);
},
[router, pathname]
);
const push = useCallback(
(...args: Parameters<typeof router.push>) => {
const [href] = args;
if (href !== pathname) {
NProgress.start();
}
router.push(...args);
},
[router, pathname]
);
return {
...router,
replace,
push,
};
}; |
Beta Was this translation helpful? Give feedback.
If you upgrade to
createNavigation
innext-intl@^3.22
, the types are a bit simplified—that should help with composition (see e.g. the updated link composition example).You should be able to call
Parameters<(typeof router)['push']>
for example to extract the arguments.I'll move this to a discussion since it seems to be more of a usage question, hope that's ok!