i18n redirection through middleware causes multiple redirection during client side transitions
See original GitHub issueVerify canary release
- I verified that the issue exists in Next.js canary release
Provide environment information
Operating System:
Platform: win32
Arch: x64
Version: Windows 10 Home Single Language
Binaries:
Node: 16.13.1
npm: N/A
Yarn: N/A
pnpm: N/A
Relevant packages:
next: 12.1.1
react: 17.0.2
react-dom: 17.0.2
What browser are you using? (if relevant)
Chrome
How are you deploying your application? (if relevant)
Other platform
Describe the Bug
For advanced i18n needs, I’m currently using middleware so that only some sets of pages have i18n enabled. e.g while accessing let’s say /pt/xyz redirects the user to /xyz since we don’t have the Portuguese content for that particular page.
The below piece of code works well when I directly enter the URL in the browser. But causes multiple redirections when I click a link on the page which causes a client-side transition to a different page
if (!requested_page_is_i18n_enabled && locale !== 'en') {
const url = nextUrl.clone();
url.locale = 'en';
return NextResponse.redirect(url);
}
Expected Behavior
Looks like the return NextResponse.redirect(url);
doesn’t work properly when we click on a Link component
whatever changes I apply to nextUrl, it seems like it doesn’t get applied but when I do a hard refresh, it works as expected
To Reproduce
/* eslint-disable no-console */
import { NextResponse } from 'next/server';
import supportedLanguages from '../public/locales/supportedLanguages';
const PUBLIC_FILE = /\.(.*)$/;
const pathsWhereLocalesAreEnabled = [
'/jobs',
'/jobs/[id]',
'/remote-developer-jobs',
];
export function middleware(req) {
try {
const { nextUrl, headers } = req;
const { locale } = nextUrl;
if (PUBLIC_FILE.test(nextUrl.pathname)) {
return undefined;
}
if (nextUrl.pathname.includes('/api')) {
return undefined;
}
const browserDefaultLocale =
headers.get('accept-language')?.split(',')?.[0] || 'en';
if (locale === 'en' && browserDefaultLocale === 'en') {
return undefined;
}
const websiteLocale = supportedLanguages.includes(browserDefaultLocale)
? browserDefaultLocale
: 'en';
const requested_page_is_i18n_enabled = pathsWhereLocalesAreEnabled.includes(
req.page.name,
);
console.log(nextUrl.toString());
if (!requested_page_is_i18n_enabled && locale !== 'en') {
const url = nextUrl.clone();
url.locale = 'en';
return NextResponse.redirect(url);
}
if (requested_page_is_i18n_enabled) {
const { locale } = nextUrl;
const url = nextUrl.clone();
if (locale === websiteLocale && locale === 'en') return undefined;
if (locale === 'en') {
url.locale = websiteLocale;
return NextResponse.redirect(url);
}
return undefined;
}
// If everything else falls through continue on with response as normal
return undefined;
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
}
}
This is the code I am using, I don’t know how I can share how to reproduce this since I’m working on my company’s website. Pls help 😦
Issue Analytics
- State:
- Created a year ago
- Reactions:3
- Comments:7 (1 by maintainers)
Top GitHub Comments
Thanks a lot @javivelasco!
@erming that worked for me, thank you so much!