Next.js SSR下next-translate子页面语言切换失效问题求助
Next.js SSR + next-translate 动态路由页面服务端语言与路径不一致问题解决
问题描述
采用Next.js SSR结合next-translate实现多语言切换时,出现以下异常:
- 无需服务端加载数据的静态页面,切换语言后运行正常
- 动态路由页面(如
/offer/[slug].tsx)前端URL显示en语言前缀(例:http://localhost:3000/en/offer/oferid),但服务端返回波兰语(pl)内容 - 服务端日志显示编译该动态页面时使用的locale为
pl,与URL中的语言标识不符:
next-translate - compiled page: /offer/[slug] - locale: pl - namespaces: common, offer, talent, job-board, common - used loader: getServerSideProps
解决方案
1. 修复getServerSideProps的locale获取逻辑
动态路由页面的getServerSideProps必须从context对象中直接读取当前locale,避免依赖全局变量或缓存值:
export async function getServerSideProps(context) { // 直接从context获取next-translate注入的当前locale const { locale } = context; const { slug } = context.params; // 使用locale请求对应语言的服务端数据 const response = await fetch(`https://your-api-domain/offers/${slug}?lang=${locale}`); const offerData = await response.json(); return { props: { offerData, }, }; }
2. 检查next-translate配置正确性
确保next-translate.config.js中配置了正确的语言列表、默认语言,且开启SSR支持:
module.exports = { locales: ['en', 'pl'], defaultLocale: 'pl', // 根据业务需求设置默认语言 pages: { '*': ['common'], '/offer/[slug]': ['offer', 'common'], // 绑定动态页面需要的语言命名空间 }, ssr: true, // 强制开启SSR模式 };
3. 验证语言切换的Cookie设置
next-translate默认通过NEXT_LOCALE Cookie存储当前语言,服务端需正确读取该Cookie。若自定义语言切换逻辑,需确保切换时正确设置Cookie:
// 前端语言切换函数 const switchLanguage = (targetLang) => { // 调用接口设置Cookie fetch('/api/set-locale', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ lang: targetLang }), }).then(() => { // 跳转到对应语言的当前页面 const currentPath = window.location.pathname.replace(/^\/[a-z]{2}/, ''); window.location.href = `/${targetLang}${currentPath}`; }); }; // pages/api/set-locale.ts 接口实现 export default function handler(req, res) { const { lang } = req.body; // 设置有效期1年的NEXT_LOCALE Cookie res.setHeader('Set-Cookie', `NEXT_LOCALE=${lang}; Path=/; Max-Age=31536000; HttpOnly`); res.status(200).json({ success: true }); }
4. 清除开发环境缓存
开发环境的缓存可能导致旧locale值被保留,执行以下命令清除缓存并重启服务:
rm -rf .next npm run dev
执行完以上步骤后,重新访问动态路由页面,检查服务端日志,确认编译页面时使用的locale与URL中的语言标识一致即可。
内容的提问来源于stack exchange,提问作者GaryNJ
相关产品推荐
相关产品推荐

