Next.js13 App Router无路由/域名前缀国际化实现问题
解决Next.js 13 App Router无路由/多域名国际化问题
核心逻辑
由于是登录后才可访问的应用,用户语言偏好存储在数据库中,核心是服务端获取用户语言 + 全局注入i18n配置,完全摆脱路由/域名依赖。
步骤1:适配App Router的react-i18next基础配置
先修正基础配置,解决翻译键名显示问题:
- 安装依赖:
npm install i18next react-i18next i18next-resources-to-backend - 创建
i18n.js配置文件:import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; import resourcesToBackend from 'i18next-resources-to-backend'; i18n .use(initReactI18next) .use(resourcesToBackend((language, namespace, callback) => { // 从本地locales目录加载翻译文件,也可替换为API拉取逻辑 import(`./locales/${language}/${namespace}.json`) .then(res => callback(null, res)) .catch(err => callback(err, null)); })) .init({ lng: 'en', // 默认语言,后续会被用户偏好覆盖 fallbackLng: 'en', interpolation: { escapeValue: false }, // React自带转义,无需重复处理 react: { useSuspense: false }, // 适配App Router,避免Suspense相关报错 }); export default i18n;
步骤2:根布局中服务端获取用户语言并全局生效
在app/layout.js(根布局)中,从数据库拉取当前登录用户的语言偏好,同步更新i18n配置:
import { I18nextProvider } from 'react-i18next'; import i18n from '@/i18n'; // 替换为你的登录会话获取逻辑(比如NextAuth) import { getServerSession } from 'next-auth/next'; // 自定义数据库查询函数,根据用户ID获取语言偏好 import { getUserLang } from '@/lib/db'; export default async function RootLayout({ children }) { const session = await getServerSession(); let userLang = 'en'; if (session?.user?.id) { userLang = await getUserLang(session.user.id); } // 更新i18n当前语言 i18n.changeLanguage(userLang); return ( <html lang={userLang}> <body> <I18nextProvider i18n={i18n}> {children} </I18nextProvider> </body> </html> ); }
步骤3:组件中正确使用翻译
客户端组件
'use client'; import { useTranslation } from 'react-i18next'; export default function Dashboard() { const { t } = useTranslation(); return ( <div> <h1>{t('dashboard.title')}</h1> <p>{t('dashboard.welcome')}</p> </div> ); }
服务器组件
直接调用i18n的t函数即可:
import i18n from '@/i18n'; import { getUserLang } from '@/lib/db'; import { getServerSession } from 'next-auth/next'; export default async function ServerComponent() { const session = await getServerSession(); const userLang = session?.user?.id ? await getUserLang(session.user.id) : 'en'; i18n.changeLanguage(userLang); return <h1>{i18n.t('server.title')}</h1>; }
常见问题排查
- 翻译文件路径:确保
locales/[语言]/[命名空间].json目录结构正确,键名与组件中调用的一致 - 语言值匹配:数据库返回的语言标识(如
zh-CN)要和翻译文件目录名完全一致 - Hydration 不匹配:根布局中
html标签的lang属性要和i18n设置的语言保持一致 - Suspense 配置:如果需要在客户端组件中使用Suspense,可将
i18n.js中的useSuspense设为true,并在组件外层包裹<Suspense>
内容的提问来源于stack exchange,提问作者Herza Islad
相关产品推荐
相关产品推荐

