Next.js 13 国际化问题:动态路由context.locale异常
Next.js 动态路由 context.locale 跳转异常问题
问题现象
- 动态路由
pages/song/[id]场景下:- 直接在浏览器输入完整地址(如
/de/song/exampleSong)访问,context.locale正确,页面显示对应语言 - 通过站内
Link组件或router.push跳转时,目标页面的locale被强制设置为next.config.js中i18n配置的defaultLocale,但浏览器地址栏显示的 locale 路径正确(如/de/song/...) - 刷新页面后,应用内的
locale恢复正常 - Middleware 中打印的
locale始终正确,但页面组件内读取时异常
- 直接在浏览器输入完整地址(如
环境依赖
"next": "^13.3.0", "next-intl": "^2.19.1", "react": "^18.2.0", "react-click-away-listener": "^2.2.3", "react-dom": "^18.2.0", "react-gtm-module": "^2.0.11"
可行解决方案
1. 跳转时显式指定 locale
在使用 Link 或 router.push 时,手动传入 locale 参数,避免 Next.js 自动推断错误:
- 用
Link组件:<Link href="/song/[id]" as={`/${locale}/song/${songId}`} locale={locale}> 查看歌曲详情 </Link> - 用
router.push:import { useRouter } from 'next/router'; const router = useRouter(); router.push(`/${locale}/song/${songId}`, undefined, { locale });
2. 页面内手动从URL提取 locale
利用地址栏路径的正确性,在动态路由页面中直接解析URL获取locale,替代对 context.locale 的依赖:
import { useRouter } from 'next/router'; export default function SongPage() { const router = useRouter(); // 从路径首段提取locale const currentLocale = router.asPath.split('/')[1]; // 后续业务逻辑使用currentLocale return ( <div>当前语言环境:{currentLocale}</div> ); }
3. 同步 next-intl 与路由 locale
在 _app.js 中监听路由变化,强制同步 next-intl 的 locale 与当前路由的 locale:
import { useRouter } from 'next/router'; import { IntlProvider } from 'next-intl'; import { useEffect } from 'react'; function MyApp({ Component, pageProps }) { const router = useRouter(); const { locale } = router; useEffect(() => { // 路由变化时校验并同步locale if (router.locale !== pageProps.locale) { router.replace(router.asPath, undefined, { locale: router.locale }); } }, [router]); return ( <IntlProvider locale={locale} messages={pageProps.messages}> <Component {...pageProps} /> </IntlProvider> ); } export default MyApp;
4. 关闭 Next.js 自动 locale 检测
在 next.config.js 中禁用自动locale检测,避免与手动设置的locale冲突:
module.exports = { i18n: { locales: ['en', 'de'], // 替换为你的语言列表 defaultLocale: 'en', localeDetection: false } };
内容的提问来源于stack exchange,提问作者Henning
相关产品推荐
相关产品推荐

