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
相关产品推荐
相关产品推荐

