You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 20:47:02