Open blackrabbit944 opened 1 year ago
Same here. Latest example only works if I am already in e.g. localhost:3000/en/news
. If I go to localhost:3000
it will throw 404.
In my case must declare explicitly a locale in the URL to view the homepage, if no locale is provided it shows a 404. http://localhost:3001/ -> don't work http://localhost:3001/en-US -> work
Using app router with: "next": "^13.4.9", "next-translate": "^2.5.2", "next-translate-plugin": "^2.5.2",
Any way to have homepage working on default language?
We are investigating a better way to fix that, because now i18n has some trobles with the middleware (issue https://github.com/vercel/next.js/issues/49883), but for now can be solved adding a app/route.(js|ts)
file:
import { NextRequest } from 'next/server';
import { redirect } from 'next/navigation';
import i18nConfig from '../../i18n';
export async function GET(request: NextRequest) {
const userPreferredLanguage =
request.headers.get('accept-language')?.split(',')?.[0] ??
i18nConfig.defaultLocale;
const lang = i18nConfig.locales.includes(userPreferredLanguage)
? userPreferredLanguage
: i18nConfig.defaultLocale;
return redirect(`/${lang}${request.nextUrl.pathname.toLowerCase()}`);
}
src/app
├── [lang]
│ │── layout.tsx
│ ├── loading.tsx
│ ├── page.tsx
└── route.ts
I have the same problem using the regular Next Pages, any way to solve it? Doesn't happen on localhost, but it does on Vercel, if I click on any link on the page doesn't happen and only occurs on the home page.
next 13.4.4 next-translate 2.4.4 next-translate-plugin 2.4.4
I have the same problem using the regular Next Pages, any way to solve it? Doesn't happen on localhost, but it does on Vercel, if I click on any link on the page doesn't happen and only occurs on the home page.
next 13.4.4 next-translate 2.4.4 next-translate-plugin 2.4.4
I think only happens when accept-language
is not comming. By default we are adding the i18n
in the next.config.js
config and is doing this redirect to the prefered language of the user. However when the user doesn't have a preferred language or accept-language
header is not comming, then is displaying this 404. In order to solve it is better for now to implement the solution I proposed above.
How can I achieve that in the pages router?
How can I achieve that in the pages router?
This problem is not related with pages
router. With pages
router there aren't routing problems because all the i18n routing part is implemented in the core of Next.js (what next-translate
uses under the hood): https://nextjs.org/docs/pages/building-your-application/routing/internationalization
How can I achieve that in the pages router?
This problem is not related with
pages
router. Withpages
router there aren't routing problems because all the i18n routing part is implemented in the core of Next.js (whatnext-translate
uses under the hood): nextjs.org/docs/pages/building-your-application/routing/internationalization
Should I open another issue then?
I'm getting a production error on Vercel using the pages router. Only happens on the homepage and if the person is using one of my locales specified in the i18n.json without being the default one, doesn't happen on localhost or if the person uses a link in my site that points to the home.
Live site: https://spotify-api-challenge.vercel.app/pt-BR
Repo: https://github.com/ygorp2/spotify-api-challenge/tree/without-oauth
I have the same problem using the App Router, homepage 404 error.
next 13.4.12 next-translate 2.5.2 next-translate-plugin 2.5.2
We are investigating a better way to fix that, because now i18n has some trobles with the middleware (issue vercel/next.js#49883), but for now can be solved adding a
app/route.(js|ts)
file:import { NextRequest } from 'next/server'; import { redirect } from 'next/navigation'; import i18nConfig from '../../i18n'; export async function GET(request: NextRequest) { const userPreferredLanguage = request.headers.get('accept-language')?.split(',')?.[0] ?? i18nConfig.defaultLocale; const lang = i18nConfig.locales.includes(userPreferredLanguage) ? userPreferredLanguage : i18nConfig.defaultLocale; return redirect(`/${lang}${request.nextUrl.pathname.toLowerCase()}`); }
src/app ├── [lang] │ │── layout.tsx │ ├── loading.tsx │ ├── page.tsx └── route.ts
Hi again, I found that this workaround works when server is already up but once you shut down and start server again it throws ERR_TOO_MANY_REDIRECTS because of redirect
.
I have the same problem using the regular Next Pages, any way to solve it? Doesn't happen on localhost, but it does on Vercel, if I click on any link on the page doesn't happen and only occurs on the home page. next 13.4.4 next-translate 2.4.4 next-translate-plugin 2.4.4
I think only happens when
accept-language
is not comming. By default we are adding thei18n
in thenext.config.js
config and is doing this redirect to the prefered language of the user. However when the user doesn't have a preferred language oraccept-language
header is not comming, then is displaying this 404. In order to solve it is better for now to implement the solution I proposed above.
I am still getting this error in production at my homepage in the /app
router, when I go to /en-US
:
Error: Invariant: The detected locale does not match the locale in the query. Expected to find 'nl-NL' in '/en-US' but found 'en-US'}
When I go to nl-NL
as default, it works fine.
With route.ts:
import { redirect } from 'next/navigation';
import i18nConfig from '../../i18n.json'
export async function GET(request: NextRequest) {
const userPreferredLanguage =
request.headers.get('accept-language')?.split(',')?.[0] ??
i18nConfig.defaultLocale;
const lang = i18nConfig.locales.includes(userPreferredLanguage)
? userPreferredLanguage
: i18nConfig.defaultLocale;
return redirect(`/${lang}${request.nextUrl.pathname.toLowerCase()}`);
}
With i18n.json:
"locales": ["nl-NL", "en-US", "tr-TR", "pl-PL"],
"defaultLocale": "nl-NL",
"pages": {
"*": ["common", "home"],
"/[lang]": ["pricing", "faq", "faqFreelancer", "freelancer", "search"]
}
}
And in the RootLayout:
// Layouts must accept a children prop.
// This will be populated with nested layouts or pages
children,
}: {
children: React.ReactNode
}) {
const { lang } = useTranslation('common')
if (!i18n.locales.includes(lang)) redirect(`/${i18n.defaultLocale}/${lang}`)
return (
<html lang={lang} suppressHydrationWarning>
<body
className={cn(
"min-h-screen antialiased",
fontSans.variable,
)}>
<Header variant="default" />
<main>{children}
</main>
<Footer/>
</body>
</html>
)
}
Am I forgetting something?
versions:
next 13.4.9
next-translate 2.5.3
next-translate-plugin 2.5.3
How can I achieve that in the pages router?
This problem is not related with
pages
router. Withpages
router there aren't routing problems because all the i18n routing part is implemented in the core of Next.js (whatnext-translate
uses under the hood): nextjs.org/docs/pages/building-your-application/routing/internationalizationShould I open another issue then?
I'm getting a production error on Vercel using the pages router. Only happens on the homepage and if the person is using one of my locales specified in the i18n.json without being the default one, doesn't happen on localhost or if the person uses a link in my site that points to the home.
Live site: https://spotify-api-challenge.vercel.app/pt-BR
Repo: https://github.com/ygorp2/spotify-api-challenge/tree/without-oauth
Did you solve this issue? I have it in /app
Did you solve this issue? I have it in
/app
No, it still gives a 404 unluckily.
I did solve it with what @aralroca said but with these specific versions of next
and next-translate
. I tried to bump up next
and next-translate
and noticed his solution stopped working, so i can say it deffo works on these versions.
"next": "13.4.12",
"next-translate": "^2.5.2",
"next-translate-plugin": "^2.5.2",
I did solve it with what @aralroca said but with these specific versions of
next
andnext-translate
. I tried to bump upnext
andnext-translate
and noticed his solution stopped working, so i can say it deffo works on these versions."next": "13.4.12", "next-translate": "^2.5.2", "next-translate-plugin": "^2.5.2",
For me even with this versions, I keep getting:
Error: Invariant: The detected locale does not match the locale in the query. Expected to find 'nl-NL
I did solve it with what @aralroca said but with these specific versions of
next
andnext-translate
. I tried to bump upnext
andnext-translate
and noticed his solution stopped working, so i can say it deffo works on these versions."next": "13.4.12", "next-translate": "^2.5.2", "next-translate-plugin": "^2.5.2",
For me even with this versions, I keep getting:
Error: Invariant: The detected locale does not match the locale in the query. Expected to find 'nl-NL
In my personal use case i saw that there's sooooo many variants of english and i don't really care about the minor differences between spelling for en-GB
or en-US
, and the rest en-029, en-AU, en-BZ, en-CA, en-cb, en-IE, en-IN
and etc, so because in MY USE CASE i don't care about the variants i adjusted it to ignore the last part after the -
and only detect the first en
.
route.ts
import { NextRequest } from 'next/server';
import { redirect } from 'next/navigation';
import i18nConfig from '../../i18n';
export async function GET(request: NextRequest) {
let userPreferredLanguage =
request.headers.get('accept-language')?.split(',')?.[0] ??
i18nConfig.defaultLocale;
const regex = /en-[A-Z]{2}/g;
const englishVariants = userPreferredLanguage.match(regex);
if (englishVariants)
userPreferredLanguage = userPreferredLanguage.replace(
englishVariants[0],
'en',
);
const lang = i18nConfig.locales.includes(userPreferredLanguage)
? userPreferredLanguage
: i18nConfig.defaultLocale;
return redirect(`/${lang}${request.nextUrl.pathname.toLowerCase()}`);
}
i18n.js
const i18n = {
locales: ['en', 'sw'],
defaultLocale: 'en',
pages: {
'*': ['common'],
'/[lang]': ['home'],
'/[lang]/search': ['search'],
'/[lang]/ticket': ['ticket'],
'/[lang]/ticket/review': ['ticket'],
},
};
module.exports = i18n;
looking at your error Error: Invariant: The detected locale does not match the locale in the query. Expected to find 'nl-NL
, I suggest you log and see what locale comes. console.log this request.headers.get('accept-language')?.split(',')?.[0]
so you can know what comes in the locale. If nothing comes then you have another issue
I did solve it with what @aralroca said but with these specific versions of
next
andnext-translate
. I tried to bump upnext
andnext-translate
and noticed his solution stopped working, so i can say it deffo works on these versions."next": "13.4.12", "next-translate": "^2.5.2", "next-translate-plugin": "^2.5.2",
For me even with this versions, I keep getting:
Error: Invariant: The detected locale does not match the locale in the query. Expected to find 'nl-NL
In my personal use case i saw that there's sooooo many variants of english and i don't really care about the minor differences between spelling for
en-GB
oren-US
, and the resten-029, en-AU, en-BZ, en-CA, en-cb, en-IE, en-IN
and etc, so because in MY USE CASE i don't care about the variants i adjusted it to ignore the last part after the-
and only detect the firsten
.route.ts
import { NextRequest } from 'next/server'; import { redirect } from 'next/navigation'; import i18nConfig from '../../i18n'; export async function GET(request: NextRequest) { let userPreferredLanguage = request.headers.get('accept-language')?.split(',')?.[0] ?? i18nConfig.defaultLocale; const regex = /en-[A-Z]{2}/g; const englishVariants = userPreferredLanguage.match(regex); if (englishVariants) userPreferredLanguage = userPreferredLanguage.replace( englishVariants[0], 'en', ); const lang = i18nConfig.locales.includes(userPreferredLanguage) ? userPreferredLanguage : i18nConfig.defaultLocale; return redirect(`/${lang}${request.nextUrl.pathname.toLowerCase()}`); }
i18n.js
const i18n = { locales: ['en', 'sw'], defaultLocale: 'en', pages: { '*': ['common'], '/[lang]': ['home'], '/[lang]/search': ['search'], '/[lang]/ticket': ['ticket'], '/[lang]/ticket/review': ['ticket'], }, }; module.exports = i18n;
looking at your error
Error: Invariant: The detected locale does not match the locale in the query. Expected to find 'nl-NL
, I suggest you log and see what locale comes. console.log thisrequest.headers.get('accept-language')?.split(',')?.[0]
so you can know what comes in the locale. If nothing comes then you have another issue
I changed the configuration to match exactly what you provided, but I still encounter the same error. When I set the defaultLocale to 'en'
, it continuously redirects me from /en
to /en/
or vice versa.
The console log, as you pointed out, indeed returns undefined
.
Interestingly, this problem is unique to the next-translate package. I tried switching to next-intl
and didn't experience any issues. However, transitioning completely to next-intl
would take several days. I really like the next-translate
package, so I hope I can find a solution to this issue.
if you're getting undefined
when you log request.headers.get('accept-language')?.split(',')?.[0]
in your route.ts
then try doing this on your layout.tsx
export default function RootLayout({
children,
params: { lang },
}: {
children: React.ReactNode;
params: { lang: string };
}) {
// Redirect to default locale if lang is not supported.
if (!i18n.locales.includes(lang)) redirect(`/${i18n.defaultLocale}/`); // <-------- ADD THIS LINE HERE IS KEY
return (
<html lang={lang}> // <---------------- ADD THIS LINE HERE IS KEY
<body className={`${manrope.variable}`}>
<Providers>{children}</Providers>
</body>
</html>
);
}
if you're getting
undefined
when you logrequest.headers.get('accept-language')?.split(',')?.[0]
in yourroute.ts
then try doing this on yourlayout.tsx
export default function RootLayout({ children, params: { lang }, }: { children: React.ReactNode; params: { lang: string }; }) { // Redirect to default locale if lang is not supported. if (!i18n.locales.includes(lang)) redirect(`/${i18n.defaultLocale}/`); // <-------- ADD THIS LINE HERE IS KEY return ( <html lang={lang}> // <---------------- ADD THIS LINE HERE IS KEY <body className={`${manrope.variable}`}> <Providers>{children}</Providers> </body> </html> ); }
if you're getting
undefined
when you logrequest.headers.get('accept-language')?.split(',')?.[0]
in yourroute.ts
then try doing this on yourlayout.tsx
export default function RootLayout({ children, params: { lang }, }: { children: React.ReactNode; params: { lang: string }; }) { // Redirect to default locale if lang is not supported. if (!i18n.locales.includes(lang)) redirect(`/${i18n.defaultLocale}/`); // <-------- ADD THIS LINE HERE IS KEY return ( <html lang={lang}> // <---------------- ADD THIS LINE HERE IS KEY <body className={`${manrope.variable}`}> <Providers>{children}</Providers> </body> </html> ); }
Even with that I am getting a 500 internal server error:
Error: Invariant: The detected locale does not match the locale in the query. Expected to find 'nl' in '/en' but found 'en'}
at I18NProvider.fromQuery (/var/task/node_modules/next/dist/server/future/helpers/i18n-provider.js:70:27)```
if you're getting
undefined
when you logrequest.headers.get('accept-language')?.split(',')?.[0]
in yourroute.ts
then try doing this on yourlayout.tsx
export default function RootLayout({ children, params: { lang }, }: { children: React.ReactNode; params: { lang: string }; }) { // Redirect to default locale if lang is not supported. if (!i18n.locales.includes(lang)) redirect(`/${i18n.defaultLocale}/`); // <-------- ADD THIS LINE HERE IS KEY return ( <html lang={lang}> // <---------------- ADD THIS LINE HERE IS KEY <body className={`${manrope.variable}`}> <Providers>{children}</Providers> </body> </html> ); }
if you're getting
undefined
when you logrequest.headers.get('accept-language')?.split(',')?.[0]
in yourroute.ts
then try doing this on yourlayout.tsx
export default function RootLayout({ children, params: { lang }, }: { children: React.ReactNode; params: { lang: string }; }) { // Redirect to default locale if lang is not supported. if (!i18n.locales.includes(lang)) redirect(`/${i18n.defaultLocale}/`); // <-------- ADD THIS LINE HERE IS KEY return ( <html lang={lang}> // <---------------- ADD THIS LINE HERE IS KEY <body className={`${manrope.variable}`}> <Providers>{children}</Providers> </body> </html> ); }
Even with that I am getting a 500 internal server error:
Error: Invariant: The detected locale does not match the locale in the query. Expected to find 'nl' in '/en' but found 'en'} at I18NProvider.fromQuery (/var/task/node_modules/next/dist/server/future/helpers/i18n-provider.js:70:27)```
hit me up at abraham@itule.me then we'll jump on a call, i'll help you fix it.
if you're getting
undefined
when you logrequest.headers.get('accept-language')?.split(',')?.[0]
in yourroute.ts
then try doing this on yourlayout.tsx
export default function RootLayout({ children, params: { lang }, }: { children: React.ReactNode; params: { lang: string }; }) { // Redirect to default locale if lang is not supported. if (!i18n.locales.includes(lang)) redirect(`/${i18n.defaultLocale}/`); // <-------- ADD THIS LINE HERE IS KEY return ( <html lang={lang}> // <---------------- ADD THIS LINE HERE IS KEY <body className={`${manrope.variable}`}> <Providers>{children}</Providers> </body> </html> ); }
if you're getting
undefined
when you logrequest.headers.get('accept-language')?.split(',')?.[0]
in yourroute.ts
then try doing this on yourlayout.tsx
export default function RootLayout({ children, params: { lang }, }: { children: React.ReactNode; params: { lang: string }; }) { // Redirect to default locale if lang is not supported. if (!i18n.locales.includes(lang)) redirect(`/${i18n.defaultLocale}/`); // <-------- ADD THIS LINE HERE IS KEY return ( <html lang={lang}> // <---------------- ADD THIS LINE HERE IS KEY <body className={`${manrope.variable}`}> <Providers>{children}</Providers> </body> </html> ); }
Even with that I am getting a 500 internal server error:
Error: Invariant: The detected locale does not match the locale in the query. Expected to find 'nl' in '/en' but found 'en'} at I18NProvider.fromQuery (/var/task/node_modules/next/dist/server/future/helpers/i18n-provider.js:70:27)```
hit me up at abraham@itule.me then we'll jump on a call, i'll help you fix it.
Hey, thanks for the offer but I switched to next-intl
!
Same problem here. Is it a nextjs bug? Know anybody when it will be fixed?
Any idea what is that error? I have a build that works locally but fails on Vercel with that exact same error.
I tried on both node 20.x
and 18.x
without success.
My Next version is 13.4.7
(I also tried up to 13.4.9
).
I used the strategy proposed here: https://www.izoukhai.com/blog/implement-internationalization-i18n-in-next-13-actually-working
The error I get is:
Error: Invariant: The detected locale does not match the locale in the query. Expected to find 'default' in '/fr' but found 'fr'}
at I18NProvider.fromQuery (/var/task/node_modules/next/dist/server/future/helpers/i18n-provider.js:70:27)
at Object.fn (/var/task/node_modules/next/dist/server/next-server.js:973:106)
at Router.execute (/var/task/node_modules/next/dist/server/router.js:315:44)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async NextNodeServer.runImpl (/var/task/node_modules/next/dist/server/base-server.js:615:29)
at async NextNodeServer.handleRequestImpl (/var/task/node_modules/next/dist/server/base-server.js:546:20)
I tried to look at I18NProvider.fromQuery
and it seems there is something not right here because the code looks like this:
fromQuery(pathname, query) {
const detectedLocale = query.__nextLocale;
// If a locale was detected on the query, analyze the pathname to ensure
// that the locale matches.
if (detectedLocale) {
const analysis = this.analyze(pathname);
// If the analysis contained a locale we should validate it against the
// query and strip it from the pathname.
if (analysis.detectedLocale) {
if (analysis.detectedLocale !== detectedLocale) {
throw new Error(`Invariant: The detected locale does not match the locale in the query. Expected to find '${detectedLocale}' in '${pathname}' but found '${analysis.detectedLocale}'}`);
}
pathname = analysis.pathname;
}
}
return {
pathname,
detectedLocale,
inferredFromDefault: query.__nextInferredLocaleFromDefault === "1"
};
}
So this error shouldn't even happen because I added the localeDetection: false
to my i18n configuration.
If we translate the error:
throw new Error(`Invariant: The detected locale does not match the locale in the query. Expected to find '${detectedLocale}' in '${pathname}' but found '${analysis.detectedLocale}'}`);
I have:
default
in detectedLocale
/fr
in pathname
fr
in analysis.detectedLocale
It seems the issue is with the detectedLocale
because this happens after the redirection to /fr
. I have no clue what is going on, and its hard to debug because I can't reproduce this in local dev.
The requested URL [GET] /fr?nxtPlang=fr status=500
seems strange, I have no idea what nxtPlang
param is:
Can you tried in 3.0.0-canary.1 version? (both, next-translate & next-translate-plugin). Thanks
What version of this package are you using?
What operating system, Node.js, and npm version? npm : 8.5.1 nodejs: v18.16.0
What happened?
After using npx create-next-app@latest to create a project and only adding the next-translate library, the home page cannot be accessed and a 404 error is displayed.
Whether it is /ja /en /zh or / cannot be accessed, a 404 error is displayed
What did you expect to happen?
I hope the normal home page can be displayed
Are you willing to submit a pull request to fix this bug?
I don't think I can do it
with i18n.js and next.config.js
i18n.js
next.config.js
whatever i add experimental.appDir or remove it still get 404 error
and with the nextjs config