nextjs - 💡(How to fix) Fix localePrefix: "as-needed" causes 308 redirects on locale subpaths in Next.js 16 (Turbopack) - middleware never called [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#88557Fetched 2026-04-08 02:04:28
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Author
Timeline (top)
closed ×1commented ×1labeled ×1locked ×1
RAW_BUFFERClick to expand / collapse
<html><head></head><body><h1>308 Redirect on locale-prefixed subpaths with Next.js 16 + Turbopack</h1> <h2>Description</h2> <p>When using <code>localePrefix: "as-needed"</code> (or <code>"always"</code>) with Next.js 16 and Turbopack, locale-prefixed subpaths like <code>/ja/about</code> return a <strong>308 Permanent Redirect</strong> to <code>/about</code>. The middleware is never called for these routes — the redirect happens at the framework level before middleware executes.</p> <h2>Environment</h2> <ul> <li><strong>next-intl version:</strong> 4.7.0 (also tested with 4.5.3)</li> <li><strong>Next.js version:</strong> 16.1.1</li> <li><strong>Turbopack:</strong> enabled (default in Next.js 16)</li> </ul> <h2>Reproduction</h2> <h3>Routing config</h3> <pre><code class="language-ts">import { defineRouting } from 'next-intl/routing';

export const routing = defineRouting({ locales: ['en', 'de', 'ja', 'fr'], defaultLocale: 'en', localePrefix: 'as-needed', // Also fails with 'always' localeDetection: false, alternateLinks: false, }); </code></pre>

<h3>Middleware (<code>proxy.ts</code> in Next.js 16)</h3> <pre><code class="language-ts">import createMiddleware from 'next-intl/middleware'; import { routing } from './i18n/routing';

const intlMiddleware = createMiddleware(routing);

export default async function proxy(req) { console.log('[PROXY] Processing:', req.nextUrl.pathname); return intlMiddleware(req); }

export const config = { matcher: ['/((?!api|_next|.\..).*)',] }; </code></pre>

<h3>File structure</h3> <pre><code>app/(marketing)/ [locale]/ (home)/page.tsx ← /ja works ✅ about/page.tsx ← /ja/about fails ❌ blog/page.tsx ← /ja/blog fails ❌ layout.tsx </code></pre> <h2>Expected behavior</h2>
URLExpectedActual
/ja200 (Japanese home)✅ 200
/ja/about200 (Japanese about)❌ 308 → /about
/de/pricing200 (German pricing)❌ 308 → /pricing
<h2>Actual behavior</h2> <ol> <li>Locale homepage (<code>/ja</code>) works correctly — middleware is called</li> <li>Locale subpaths (<code>/ja/about</code>, <code>/ja/blog</code>) return 308 redirect to non-prefixed path</li> <li>Middleware <code>console.log</code> is <strong>NEVER</strong> printed for subpaths — redirect happens before middleware</li> </ol> <h2>Key finding</h2> <p>The middleware/proxy function is completely bypassed for locale-prefixed subpaths. Adding debug logging shows:</p> <ul> <li><code>/ja</code> → <code>[PROXY] Processing: /ja</code> ✅</li> <li><code>/ja/about</code> → <strong>NO LOG OUTPUT</strong>, 308 redirect ❌</li> </ul> <p>This indicates the redirect is happening at the Next.js routing layer or within the next-intl plugin, not in the middleware.</p> <h2>Things tried (all failed)</h2> <ol> <li><code>localePrefix: "as-needed"</code> — 308 redirects</li> <li><code>localePrefix: "always"</code> — 308 redirects</li> <li><code>localeDetection: false</code> — 308 redirects</li> <li>Creating explicit locale folders (<code>/ja/about/page.tsx</code>) — 308 redirects</li> <li>Renamed <code>middleware.ts</code> to <code>proxy.ts</code> (Next.js 16 convention) — 308 redirects</li> <li>Upgraded next-intl from 4.5.3 to 4.7.0 — 308 redirects</li> </ol> <h2>Additional context</h2> <ul> <li>The same codebase worked before (exact commit unknown)</li> <li>Issue may be related to Turbopack specifically</li> <li>Unable to test without Turbopack as Next.js 16 uses it by default</li> <li><strong>This blocks all international SEO</strong> — crawlers see 308 redirects for non-English pages</li> </ul></body></html>

extent analysis

TL;DR

The issue can be potentially resolved by adjusting the Next.js routing configuration or exploring alternatives to the localePrefix option in next-intl.

Guidance

  1. Review Next.js 16 documentation: Ensure that the localePrefix option is correctly implemented and compatible with Turbopack.
  2. Check routing configuration: Verify that the routing configuration in next-intl is correctly set up to handle locale-prefixed subpaths.
  3. Test with explicit locale folders: Try creating explicit locale folders for subpaths (e.g., /ja/about/page.tsx) to see if it resolves the issue.
  4. Explore Turbopack configuration: Investigate if there are any Turbopack-specific configurations that can be adjusted to resolve the issue.
  5. Consider upgrading or downgrading dependencies: If possible, try upgrading or downgrading next-intl or Next.js to see if it resolves the issue.

Example

No code example is provided as the issue seems to be related to the configuration and interaction between Next.js, Turbopack, and next-intl.

Notes

The issue may be specific to the combination of Next.js 16, Turbopack, and next-intl. Further investigation and testing are required to determine the root cause and find a suitable solution.

Recommendation

Apply a workaround by adjusting the routing configuration or exploring alternative solutions to the localePrefix option, as upgrading to a fixed version is not a clear option at this point.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING