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

Next.js App Router集成Lingui:i18n.activate初始化位置咨询

解决Next.js App Router集成Lingui的预渲染初始化问题

核心原因

客户端组件的顶层代码会在Next.js预渲染(SSR/SSG)阶段在服务端执行,此时Lingui的i18n实例尚未激活locale,导致翻译函数调用报错。服务端组件、useEffect内或window判断包裹的代码不受影响,是因为这些逻辑要么在服务端提前执行,要么仅在客户端运行时触发。

解决方案:服务端预初始化 + 全局Provider传递

通过在服务端组件中提前完成Lingui的locale激活,再通过Provider将已初始化的i18n实例传递给所有客户端组件,确保预渲染和客户端运行时都能正确识别locale。

1. 封装Lingui初始化工具函数

创建lib/i18n.ts(或js)统一管理i18n实例和初始化逻辑:

import { i18n } from "@lingui/core";
import { en, zh } from "make-plural/plurals";

// 动态加载对应locale的翻译文件并初始化
export async function initI18n(locale: string) {
  const { messages } = await import(`../locales/${locale}/messages`);
  
  i18n.load({
    [locale]: messages,
  });
  i18n.activate(locale);
  
  // 注册复数规则(根据你的语言需求调整)
  i18n.pluralRules.add("en", en);
  i18n.pluralRules.add("zh", zh);
  
  return i18n;
}

export { i18n };

2. 在服务端Layout中完成全局初始化

以路由带locale的场景为例,修改app/[locale]/layout.tsx(服务端组件,无需加'use client'):

import { initI18n, i18n } from "@/lib/i18n";
import { I18nProvider } from "@lingui/react";

// 静态生成所有支持的locale路由参数
export async function generateStaticParams() {
  return [{ locale: "en" }, { locale: "zh" }];
}

export default async function RootLayout({
  children,
  params: { locale },
}: {
  children: React.ReactNode;
  params: { locale: string };
}) {
  // 服务端预初始化Lingui
  await initI18n(locale);
  
  return (
    <html lang={locale}>
      <body>
        {/* 通过Provider将已激活locale的i18n实例传递给所有子组件 */}
        <I18nProvider i18n={i18n}>
          {children}
        </I18nProvider>
      </body>
    </html>
  );
}

3. 客户端组件安全使用翻译

在客户端组件中,通过useLingui hook获取已初始化的i18n实例,或直接使用Trans组件,避免在顶层代码直接调用翻译函数:

'use client';

import { useLingui } from "@lingui/react";
import { Trans } from "@lingui/macro";

export default function UserPage() {
  const { i18n } = useLingui();
  
  // 安全使用翻译:Trans组件或通过hook获取的i18n实例
  return (
    <div>
      <Trans>Welcome to User Page</Trans>
      <p>{i18n._('user.profile.title')}</p>
    </div>
  );
}

额外注意事项

  • 禁止在客户端组件的顶层直接调用i18n._(),这类代码会在预渲染阶段执行,此时i18n可能未完成初始化。
  • 如果必须在客户端组件顶层处理翻译逻辑,可通过dynamic导入组件并禁用SSR(不推荐,会失去预渲染优势):
    import dynamic from 'next/dynamic';
    const UserPage = dynamic(() => import('./UserPage'), { ssr: false });
    

内容的提问来源于stack exchange,提问作者jaboja

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 10:25:18