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

Next.js国际化路由如何实现/[cc]/[lang]双动态参数配置

Next.js 实现 /[cc]/[lang] 双段国际化路由方案

Next.js 内置i18n能力默认仅支持单段语言前缀,要实现国家+语言的双段动态URL,可按以下步骤配置,完全兼容你现有的i18n基础配置。


方案一:适配现有Pages Router配置(无额外依赖)

1. 调整目录结构

按照嵌套动态路由规则调整pages目录结构,所有业务页面都放在二级动态路由下:

pages/
├─ [cc]/                # 一级动态段:国家/地区代码
│  └─ [lang]/           # 二级动态段:语言代码
│     ├─ index.js       # 首页 对应路径 /[cc]/[lang]
│     ├─ about.js       # 关于页 对应路径 /[cc]/[lang]/about
│     └─ ...其他业务页面
└─ _app.js

2. 修改next.config.js配置

关闭内置i18n的自动语言检测,避免和自定义双段路由冲突,新增路径重写规则:

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  i18n: {
    locales: ["en", "de"],
    defaultLocale: "en",
    localeDetection: false, // 关闭自动locale跳转
  },
  async rewrites() {
    return [
      {
        source: '/:cc/:lang/:path*',
        destination: '/:cc/:lang/:path*',
      },
    ]
  }
}

module.exports = nextConfig

3. 全局参数校验与i18n同步

在_app.js中统一校验路由参数合法性,同时同步语言参数到Next.js内置i18n实例:

// pages/_app.js
import { useRouter } from 'next/router'
import { useEffect } from 'react'

// 按业务需求调整支持的国家/地区列表
const VALID_CC = ['us', 'de', 'cn']
const VALID_LANG = ['en', 'de']
const DEFAULT_PATH = '/us/en'

export default function App({ Component, pageProps }) {
  const router = useRouter()
  const { cc, lang } = router.query

  useEffect(() => {
    if (!router.isReady) return
    // 参数不合法直接重定向到默认路径
    if (!VALID_CC.includes(cc) || !VALID_LANG.includes(lang)) {
      router.replace(DEFAULT_PATH)
      return
    }
    // 同步当前语言到Next.js i18n上下文
    if (router.locale !== lang) {
      router.push(
        { pathname: router.pathname, query: router.query },
        router.asPath,
        { locale: lang, shallow: true }
      )
    }
  }, [cc, lang, router.isReady])

  // 将cc、lang透传给所有页面,业务代码可直接从props读取
  return <Component {...pageProps} currentCC={cc} currentLang={lang} />
}

方案二:Middleware统一处理(推荐,Pages/App Router通用)

用Next.js Middleware在请求进入页面前完成路由校验、重定向、参数注入,比在_app中处理体验更好,不会出现页面加载后再跳转的闪烁问题。

1. 保持嵌套路由目录结构

和方案一的目录结构一致,Pages Router下建pages/[cc]/[lang]/*,App Router下建app/[cc]/[lang]/*即可。

2. 新增middleware文件

在项目根目录(和pages/app文件夹同级)新建middleware.js:

// middleware.js
import { NextResponse } from 'next/server'

// 配置项按业务需求修改
const VALID_CC = ['us', 'de', 'cn']
const VALID_LANG = ['en', 'de']
const DEFAULT_CC = 'us'
const DEFAULT_LANG = 'en'

export function middleware(request) {
  const { pathname } = request.nextUrl
  // 跳过静态资源、API路由、Next.js内部路径
  if (
    pathname.startsWith('/_next') ||
    pathname.startsWith('/api') ||
    pathname.includes('.')
  ) {
    return NextResponse.next()
  }

  const pathSegments = pathname.split('/').filter(Boolean)
  // 访问根路径直接重定向到默认国家+语言页
  if (pathSegments.length === 0) {
    return NextResponse.redirect(
      new URL(`/${DEFAULT_CC}/${DEFAULT_LANG}`, request.url)
    )
  }

  const [cc, lang, ...rest] = pathSegments
  // 双段参数合法则透传信息到页面
  if (VALID_CC.includes(cc) && VALID_LANG.includes(lang)) {
    const headers = new Headers(request.headers)
    headers.set('x-current-cc', cc)
    headers.set('x-current-lang', lang)
    return NextResponse.next({ request: { headers } })
  }

  // 参数不合法统一重定向到默认路径
  return NextResponse.redirect(
    new URL(`/${DEFAULT_CC}/${DEFAULT_LANG}`, request.url)
  )
}

export const config = {
  matcher: ['/:path*'],
}

页面中可以直接从请求头读取cc和lang参数,App Router下也可以直接从params prop中获取两个动态段的值。


注意事项

  • 所有站内跳转不要硬编码单段路径,统一封装带前缀的跳转逻辑,比如封装自定义Link组件自动拼接当前cc和lang,避免跳转丢失前缀。
  • 如果需要做地区默认语言映射(比如de地区默认语言为de、us地区默认语言为en),可以在Middleware中新增逻辑,访问/de时自动跳转到/de/de即可。
  • 如果使用App Router,不需要在next.config.js中配置内置i18n项,直接配合next-intl等第三方i18n库读取lang参数切换语言即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 13:24:21