NextJS自定义路由:支持国家与语言编码的实现方案咨询
实现带前置国家编码的多语言路由(适配next-intl)
核心思路
基于Next.js App Router,将countryCode和languageCode作为动态路由参数,扩展next-intl的能力,同时管理国家与语言上下文。
1. 目录结构设计
按照动态路由规则搭建页面结构,覆盖业务路径:
app/ ├─ [countryCode]/ │ ├─ [languageCode]/ │ │ ├─ products/ │ │ │ └─ page.js │ │ ├─ categories/ │ │ │ └─ page.js │ │ └─ layout.js # 嵌套布局,处理国家/语言参数 └─ layout.js # 根布局
2. 初始化next-intl并注入国家上下文
在app/[countryCode]/[languageCode]/layout.js中,获取路由参数、校验合法性后初始化next-intl,同时将国家编码存入上下文:
import { createIntl, createIntlCache, IntlProvider } from 'next-intl'; import { createContext, useContext } from 'react'; import { redirect } from 'next/navigation'; // 创建国家上下文 const CountryContext = createContext(null); export const useCountry = () => useContext(CountryContext); export default async function LocaleLayout({ children, params: { countryCode, languageCode } }) { // 自定义合法的国家/语言列表 const validCountries = ['us', 'ca', 'mx']; const validLanguages = ['en', 'es', 'fr']; // 非法参数重定向到默认路由 if (!validCountries.includes(countryCode) || !validLanguages.includes(languageCode)) { return redirect('/us/en/products'); } // 初始化next-intl const cache = createIntlCache(); const intl = createIntl({ locale: languageCode, messages: (await import(`../../../messages/${languageCode}.json`)).default }); return ( <IntlProvider value={intl}> <CountryContext.Provider value={countryCode}> {children} </CountryContext.Provider> </IntlProvider> ); }
3. 自定义本地化链接组件
封装自动携带当前国家/语言参数的Link组件,避免手动拼接路由:
'use client'; import { useParams } from 'next/navigation'; import Link from 'next/link'; export default function LocalizedLink({ href, children, ...props }) { const { countryCode, languageCode } = useParams(); const fullHref = `/${countryCode}/${languageCode}${href}`; return <Link href={fullHref} {...props}>{children}</Link>; }
使用示例:
<LocalizedLink href="/products">查看产品</LocalizedLink>
4. 静态页面预渲染(可选)
若需要SSG,在页面的page.js中通过generateStaticParams生成所有合法的国家/语言组合:
import { useCountry, useIntl } from '../layout'; export async function generateStaticParams() { const countries = ['us', 'ca']; const languages = ['en', 'es']; return countries.flatMap(country => languages.map(language => ({ countryCode: country, languageCode: language })) ); } export default function ProductsPage() { const country = useCountry(); const intl = useIntl(); return ( <div> <h1>{intl.formatMessage({ id: 'products.title' })}</h1> <p>当前地区:{country}</p> </div> ); }
5. 根路径重定向处理
在根目录的page.js中,处理空路径访问时的重定向逻辑:
import { redirect } from 'next/navigation'; export default function RootPage() { redirect('/us/en/products'); }
内容的提问来源于stack exchange,提问作者Nesh
相关产品推荐
相关产品推荐

