Closed groomain closed 1 year ago
@groomain could you share your next.config.js and the TypeScript error you're encountering?
{
reactStrictMode: true,
defaultLocale: "fr",
locales: ["fr", "en"],
}
@groomain Thanks, and the TypeScript error?
in router.push({ pathname, query }, asPath, { locale: nextLocale }) pathname need to be one of the route. but pathname type in router is all the routes
Could you paste the TypeScript error exactly as output by the compiler?
No overload matches this call.
Overload 1 of 3, '(url: Route, as?: string | undefined, options?: TransitionOptions | undefined): Promise<boolean>', gave the following error.
Argument of type '{ pathname: "/route-a" | "route-b" | more ...>; }' is not assignable to parameter of type 'Route'.
Type '{ pathname: "/route-a" | "route-b" | more ...>; }' is not assignable to type '{ pathname: "/route-a"; query?: { [key: string]: string | string[] | undefined; } | undefined; }'.
Types of property 'pathname' are incompatible.
Type '"/route-a" | "route-b"' is not assignable to type '"/route-a"'.
Type '"/a-word"' is not assignable to type '"/route-a"'.
Overload 2 of 3, '(url: "/route-a" | "route-b", as?: string | undefined, options?: TransitionOptions | undefined): Promise<...>', gave the following error.
Argument of type '{ pathname: "/route-a" | "route-b" | more ...>; }' is not assignable to parameter of type '"/route-a" | "route-b"'.
Overload 3 of 3, '(url: { query: { [key: string]: string | string[] | undefined; }; }, as?: string | undefined, options?: TransitionOptions | undefined): Promise<boolean>', gave the following error.
Argument of type '{ pathname: "/route-a" | "route-b" | more ...>; }' is not assignable to parameter of type '{ query: { [key: string]: string | string[] | undefined; }; }'.
Object literal may only specify known properties, and 'pathname' does not exist in type '{ query: { [key: string]: string | string[] | undefined; }; }'.
Thanks @groomain, this looks like a bug. Is this project publicly available in GitHub? If not, could you let me know:
Could you also paste your generated nextjs-routes.d.ts?
Update: I didn't realize that you renamed your pathnames, so I mistakenly thought nextjs-routes had produced a malformed pathname
if you're using the pages or app directory? the version of nextjs-routes you're using
no sorry it's a private project it's used with page folder and the last version of nextjs-routes
@groomain I'm not able to reproduce this issue. Here's a working example using the code you've shared: https://stackblitz.com/edit/nextjs-8akbqz?file=next.config.js,package.json,pages%2Froute-a.tsx,pages%2F_app.tsx
Did you define your locales
correctly? From your shared code it looks like you're using locales
as a top level key in your next.config.js, but next requires that it's nested under i18n
: https://nextjs.org/docs/advanced-features/i18n-routing
Hi, I think it's because I have a "catching all" page. [...slug].tsx
Can you try this one? I've reproduced the error here. https://stackblitz.com/edit/nextjs-zmkzrf?file=pages/_app.ts
Ah good find. The issue here is that once you destructure pathname and query, there isn't a way to let TypeScript know that the two fit together: TS will treat them as two separate unions:
// given this router
{ pathname: '/foos/[foo]', query: { foo: string } } | { pathname: '/bars/[bar]', query: { bar: string } }
// pathname destructured becomes this:
'/foos/[foo]' | '/bars/[bar]'
// query destructured becomes this:
{ foo: string } | { bar: string }
// this correctly error, and TS can't currently track that pathname and query came from the same allowed type so it checks that all unions are allowed
{ pathname: '/foos/[foo]', query: { bar: string } }
If you want to supply the pathname and query, and you know the route you're calling useRouter on, you can supply a generic argument to useRouter to prevent this issue: https://github.com/tatethurston/nextjs-routes#query
Example: https://stackblitz.com/edit/nextjs-t5pjth?file=pages%2Froute-a.tsx,pages%2F[...slug].tsx
On v1.0.1 you can do the following, because pathname and query will be pulled off router correctly, without the TypeScript destructuring tracking issue discussed above:
router.push(router, undefined, { locale: "fr" })
or for more intent clarity:
// nextjs will load the current route if pathname is omitted
router.push({ query: router.query }, undefined, { locale: "fr" })
Thanks!
fixed!
Hi,
I tried to change the locale and stay on the same route by following nextjs exemple.
Unfortunately I have a typescript error with nextjs-routes.
I fixed it with an assertion any but maybe you have a better solution?
Thanks for your help!