fix: skip intl middleware for paths already containing a locale prefix

When localePrefix is 'always' (or 'as-needed' with a non-default locale),
paths like /en/settings already have the locale in the URL. Running them
through the next-intl middleware a second time can trigger rewrite loops,
especially when combined with a proxy basePath where the middleware's
detection of the 'current' path conflicts with the rewritten one.

Skip the intl middleware in this case — the path is already in the
canonical locale-prefixed form and no further rewriting is needed.

This makes NEXT_PUBLIC_LOCALE_PREFIX=always reliable for sub-path
deployments.
This commit is contained in:
shuki
2026-04-14 18:09:37 +02:00
committed by Linus Rath
parent 9d867cbff6
commit c690e8eb76
+9 -1
View File
@@ -34,8 +34,16 @@ export function proxy(request: NextRequest) {
const pathname = request.nextUrl.pathname;
const isAdminRoute = pathname === '/admin' || pathname.startsWith('/admin/');
// When localePrefix is 'always', paths that already have a locale prefix
// (e.g. /en/settings) should not be re-processed by the intl middleware —
// doing so can trigger rewrite loops when combined with a proxy basePath.
const locales = routing.locales as readonly string[];
const hasLocalePrefix = locales.some(
(l) => pathname === `/${l}` || pathname.startsWith(`/${l}/`)
);
let intlResponse: ReturnType<typeof intlMiddleware> | null = null;
if (!isAdminRoute) {
if (!isAdminRoute && !hasLocalePrefix) {
try {
intlResponse = intlMiddleware(request);
} catch (error) {