Next.js 14 App Router:多语言不同路径渲染同一组件方案咨询
用Next.js 14 + next-intl实现多语言路由映射(动态路径对应同一组件)
核心思路
通过路由映射配置文件结合App Router的动态路由,将不同语言的路径映射到对应组件,无需手动创建多份页面文件,同时保留原URL不跳转。
步骤实现
1. 定义路由映射配置
创建配置文件维护各语言路径与组件的对应关系,方便统一管理:
// config/routes.js export const routeMap = { en: { 'hi': 'Hi', 'seeya': 'Bye', 'about-us': 'AboutUs' }, fr: { 'allo': 'Hi', 'bye': 'Bye', 'a-propos-de-nous': 'AboutUs' }, vn: { 'xin-chao': 'Hi', 'tam-biet': 'Bye', 've-chung-toi': 'AboutUs' } }; // 反向映射:用于生成不同语言的页面链接 export const reverseRouteMap = { Hi: { en: 'hi', fr: 'allo', vn: 'xin-chao' }, Bye: { en: 'seeya', fr: 'bye', vn: 'tam-biet' }, AboutUs: { en: 'about-us', fr: 'a-propos-de-nous', vn: 've-chung-toi' } };
2. 创建动态路由页面
在app/[locale]/[slug]/目录下创建page.js,作为所有多语言路径的统一入口,根据当前语言和路径匹配对应组件:
// app/[locale]/[slug]/page.js import { getLocale } from 'next-intl/server'; import { routeMap } from '@/config/routes'; import Hi from '@/components/Hi'; import Bye from '@/components/Bye'; import AboutUs from '@/components/AboutUs'; // 组件映射表,关联标识与实际组件 const componentMap = { Hi, Bye, AboutUs }; export default async function DynamicPage({ params }) { const locale = await getLocale(); // 根据当前语言和路径slug获取组件标识 const componentKey = routeMap[locale]?.[params.slug]; // 处理无效路径,返回404 if (!componentKey) { return <div>404 - Page not found</div>; } const Component = componentMap[componentKey]; return <Component />; } // 可选:预渲染所有静态路径(SSG),提升页面加载性能 export async function generateStaticParams() { const locales = ['en', 'fr', 'vn']; const paths = []; locales.forEach(locale => { Object.keys(routeMap[locale]).forEach(slug => { paths.push({ locale, slug }); }); }); return paths; }
3. 配置next-intl中间件
确保locale被正确识别,拦截并处理多语言路由:
// middleware.js import createMiddleware from 'next-intl/middleware'; export default createMiddleware({ locales: ['en', 'fr', 'vn'], defaultLocale: 'en' }); export const config = { matcher: ['/', '/(en|fr|vn)/:path*'] };
4. 生成多语言链接
在组件中使用reverseRouteMap生成对应语言的路径,结合next-intl的翻译能力展示本地化文本:
// components/Nav.js import { useLocale, useTranslations } from 'next-intl'; import Link from 'next/link'; import { reverseRouteMap } from '@/config/routes'; export default function Nav() { const locale = useLocale(); const t = useTranslations('Nav'); return ( <nav> <Link href={`/${locale}/${reverseRouteMap.Hi[locale]}`}> {t('greeting')} </Link> <Link href={`/${locale}/${reverseRouteMap.Bye[locale]}`}> {t('farewell')} </Link> <Link href={`/${locale}/${reverseRouteMap.AboutUs[locale]}`}> {t('aboutUs')} </Link> </nav> ); }
对应的翻译文件示例(messages/en.json):
{ "Nav": { "greeting": "Hi", "farewell": "See Ya", "aboutUs": "About Us" } }
注意事项
- 404处理:如果用户输入的路径不在
routeMap中,返回自定义404组件即可。 - 静态生成:启用
generateStaticParams可以预渲染所有合法路径,适合内容固定的页面;如果是动态内容,可以改用ISR或SSR。 - 路由优先级:确保动态路由
[locale]/[slug]不会和其他静态路由冲突,比如如果有app/en/home/page.js,它会优先于动态路由匹配。
内容的提问来源于stack exchange,提问作者SpicyyRiice
相关产品推荐
相关产品推荐

