You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js i18n动态路由失效,无法根据语言头跳转求助

问题原因与解决方案

核心问题

Next.js 的自动国际化重定向逻辑仅对根路径 / 做了特殊处理,对于动态路由的裸路径(如 /client-1)不会自动根据 Accept-Language 头触发语言重定向;同时,当访问裸路径时,getStaticProps 会默认使用配置的 defaultLocale(即 en),不会主动根据请求头切换语言。

具体解决方案

1. 使用 Middleware 统一处理裸路径重定向

Next.js 12+ 提供的 Middleware 可以在请求到达页面之前拦截并处理,适合统一处理所有路由的语言重定向逻辑:

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

const locales = ['en', 'fr'];
const defaultLocale = 'en';

export function middleware(request: NextRequest) {
  // 检查请求路径是否已经包含 locale 前缀
  const pathname = request.nextUrl.pathname;
  const localeMatch = pathname.match(/^\/([a-z]{2})\/.*$/);
  if (localeMatch && locales.includes(localeMatch[1])) {
    return NextResponse.next();
  }

  // 从请求头获取优先语言
  const acceptLanguage = request.headers.get('Accept-Language');
  let targetLocale = defaultLocale;
  if (acceptLanguage) {
    const preferredLocales = acceptLanguage.split(',').map(lang => lang.split(';')[0].toLowerCase());
    targetLocale = preferredLocales.find(lang => locales.includes(lang)) || defaultLocale;
  }

  // 重定向到带 locale 前缀的路径
  return NextResponse.redirect(
    new URL(`/${targetLocale}${pathname === '/' ? '' : pathname}`, request.url)
  );
}

// 指定需要处理的路由(排除静态资源等)
export const config = {
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};

2. 确保 getStaticProps 接收正确的 locale

当用户通过 Middleware 重定向到带 locale 前缀的路径后,getStaticProps 的 context.locale 就会是对应的语言(如 fr),你可以直接使用它来获取对应语言的 CMS 数据:

// [slug].tsx
export const getStaticProps: GetStaticProps = async ({ locale, params }) => {
  // 现在 locale 会是正确的语言值(en/fr)
  console.log('Current locale:', locale);
  const clientData = await fetchClientBySlugAndLocale(params.slug, locale);
  
  return {
    props: {
      clientData,
    },
  };
};

3. 验证 getStaticPaths 生成的路径

你的 getStaticPaths 代码是正确的,已经生成了所有语言对应的路径,确保预渲染了 /en/client-1、/fr/client-1 这类带 locale 的页面,这样用户访问时可以直接命中预渲染的页面,或者通过 fallback: "blocking" 生成对应语言的页面。

补充说明

  • 不要依赖裸路径访问动态路由,通过 Middleware 强制所有请求都带上 locale 前缀,既能解决重定向问题,也能保证 getStaticProps 获取到正确的 locale。
  • 如果使用的是 Next.js 11 及以下版本,无法使用 Middleware,可以在 _app.tsx 的 getInitialProps 中处理重定向,但这种方式会失去静态生成的优势,不推荐。

内容的提问来源于stack exchange,提问作者DoHn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 03:47:50