作者:
    Creation:2026-01-10Last update:2026-06-23

    如何将现有的 Next.js 应用程序多语言化 (i18n) (i18n 指南 2026)

    www.youtube.com

    在 GitHub 上查看应用程序模板

    目录

    为什么对现有应用程序进行国际化会很困难?

    如果您曾经尝试向仅为单语言构建的应用程序中添加多种语言,您就会明白其中的痛苦。这不仅仅是“困难”,而是非常繁琐。您必须检查每个文件,找出每一个文本字符串,并将它们移动到单独的字典文件中。

    接下来才是冒险的部分:用代码钩子替换所有文本,同时保证不破坏布局或逻辑。这类工作往往会让新功能的开发停滞数周,感觉像是一场无止境的重构。

    什么是 Intlayer 编译器?

    Intlayer 编译器旨在规避这种繁琐的手动工作。您无需手动提取字符串,编译器会为您完成。它会扫描您的代码,找到文本,并使用 AI 在后台生成字典。 然后,在构建步骤期间,它会修改您的源代码以注入必要的 i18n 钩子。基本上,您可以像写单语言应用一样继续编写您的应用,而编译器会自动原生处理多语言转换。

    编译器文档:/zh/doc/compiler

    限制

    由于编译器在编译时执行代码分析和转换(注入钩子和生成字典),因此它可能会减慢应用程序的构建时间

    为了限制在活跃开发过程(dev 模式)中的影响,您可以将编译器设置为 'build-only' 模式,或在不需要时将其禁用。


    在 Next.js 应用程序中设置 Intlayer 的分步指南

      1. 安装依赖项

        使用您偏好的包管理器安装必要的包:

        bash
        npx intlayer-cli init --interactive
        --interactive 标志是可选的。如果您是 AI 代理,请使用 intlayer-cli init
        该命令将检测您的环境并安装所需的软件包。例如:
        bash
        npm install intlayer next-intlayernpm install @intlayer/babel --save-dev
        • intlayer

          核心包,提供用于配置管理、翻译、内容声明、转译和 CLI 命令的国际化工具。

        • next-intlayer

          将 Intlayer 与 Next.js 集成的包。它为 Next.js 国际化提供上下文提供程序和钩子。此外,它还包括用于将 Intlayer 与 WebpackTurbopack 集成的 Next.js 插件,以及用于检测用户首选语言环境、管理 cookie 和处理 URL 重定向的中间件。

      2. 配置您的项目

        创建一个配置文件来定义应用程序的语言:

        intlayer.config.ts
        import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  internationalization: {    locales: [Locales.ENGLISH, Locales.CHINESE],    defaultLocale: Locales.CHINESE,  },  routing: {    mode: "search-params",  },  compiler: {    /**     * 指示是否应启用编译器。     */    enabled: true,    /**     * 优化字典的输出目录。     */    output: ({ locale, key }) => `compiler/${locale}/${key}.json`,    /**     * 仅在生成的文件中插入内容,不含键。     */    noMetadata: false,    /**     * 字典键前缀     */    dictionaryKeyPrefix: "", // Remove base prefix    /**     * 指示转换后是否应保存组件。     * 这样,编译器只需运行一次即可转换应用程序,然后即可将其删除。     */    saveComponents: false,  },  ai: {    provider: "openai",    model: "gpt-5-mini",    apiKey: process.env.OPEN_AI_API_KEY,    applicationContext: "这是一个简单的地图应用程序示例",  },};export default config;
        注意:请确保您在环境变量中设置了 OPEN_AI_API_KEY
        通过此配置文件,您可以设置本地化的 URL、代理重定向、cookie 映射、内容声明的位置和扩展名、在控制台中禁用 Intlayer 日志等等。有关可用参数的完整列表,请参阅配置文档
      3. 将 Intlayer 集成到 Next.js 配置中

        配置您的 Next.js 设置以使用 Intlayer:

        next.config.ts
        import type { NextConfig } from "next";import { withIntlayer } from "next-intlayer/server";const nextConfig: NextConfig = {  /* 这里可选填写额外的 Next.js 配置 */};export default withIntlayer(nextConfig);

        Next.js 插件 withIntlayer() 用于将 Intlayer 与 Next.js 集成。它确保字典文件的构建,并在开发模式下监视它们。它在 WebpackTurbopack 环境中定义 Intlayer 环境变量。此外,它还提供别名以优化性能,并保留与服务器组件的兼容性。

      4. 配置 Babel

        Intlayer 编译器需要 Babel 来提取和优化您的内容。更新您的 babel.config.js(或 babel.config.json)以包含 Intlayer 插件:

        babel.config.js
        const {  intlayerExtractBabelPlugin,  intlayerOptimizeBabelPlugin,  getExtractPluginOptions,  getOptimizePluginOptions,} = require("@intlayer/babel");module.exports = {  presets: ["next/babel"],  plugins: [    [intlayerExtractBabelPlugin, getExtractPluginOptions()],    [intlayerOptimizeBabelPlugin, getOptimizePluginOptions()],  ],};
      5. 页面中的语言环境检测

        清空 RootLayout 的内容,并将其替换为以下示例:

        src/app/layout.tsx
        import type { Metadata } from "next";import type { ReactNode } from "react";import "./globals.css";import { IntlayerClientProvider, LocalPromiseParams } from "next-intlayer";import { getHTMLTextDir, getIntlayer } from "intlayer";import { getLocale } from "next-intlayer/server";export { generateStaticParams } from "next-intlayer";export const generateMetadata = async (): Promise<Metadata> => {  const locale = await getLocale();  const { title, description, keywords } = getIntlayer("metadata", locale);  return {    title,    description,    keywords,  };};const RootLayout = async ({  children,}: Readonly<{  children: ReactNode;}>) => {  const locale = await getLocale();  return (    <html lang={locale} dir={getHTMLTextDir(locale)}>      <IntlayerClientProvider defaultLocale={locale}>        <body>{children}</body>      </IntlayerClientProvider>    </html>  );};export default RootLayout;
      6. 声明您的内容(自动)

        启用编译器后,您不再需要手动声明内容字典(例如 .content.ts 文件)。

        相反,您只需在代码中以硬编码字符串的形式写入您的内容。Intlayer 会扫描源代码,使用配置的 AI 提供商生成翻译,并在构建编译期间自动将这些字符串替换为本地化内容。这一切都是完全自动化的。

        只需在组件中使用默认语言环境的硬编码字符串,让 Intlayer 编译器处理剩下的工作。

        page.tsx 可能看起来像这样:

        src/app/page.tsx
        import type { FC } from "react";import { IntlayerServerProvider } from "next-intlayer/server";import { getLocale } from "next-intlayer/server";const PageContent: FC = () => {return (  <>    <p>开始编辑吧!</p>    <code>src/app/page.tsx</code>  </>);};export default async function Page() {const locale = await getLocale();return (  <IntlayerServerProvider locale={locale}>    <PageContent />  </IntlayerServerProvider>);}
        • IntlayerClientProvider 用于在客户端向子组件提供语言环境。
        • IntlayerServerProvider 用于在服务器端向子组件提供语言环境。

          Layout and page cannot share a common server context because the server context system is based on a per-request data store (via React's cache mechanism), causing each "context" to be re-created for different segments of the application. Placing the provider in a shared layout would break this isolation, preventing the correct propagation of the server context values to your server components.

      7. 填写缺失的翻译

        可选

        Intlayer 提供了一个 CLI 工具来帮助您填写缺失的翻译。您可以使用 intlayer 命令来测试并从您的代码中填写缺失的翻译。

        bash
        npx intlayer test         # 测试是否有缺失的翻译
        bash
        npx intlayer fill         # 填写缺失的翻译
        有关更多详细信息,请参阅 CLI 文档
      8. 本地化路由代理中间件

        可选

        如果您希望自动将用户重定向到其偏好的语言环境,请建立代理解析中间件:

        src/proxy.ts
        export { intlayerProxy as proxy } from "next-intlayer/proxy";export const config = {  matcher:    "/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",};

        intlayerProxy 用于检测用户的首选语言环境,并根据 配置文件设置 将其重定向到适当的 URL。此外,它还支持将用户的首选语言环境保存在 cookie 中。

      9. 更改内容语言环境

        可选

        在 Next.js 中更改内容语言环境的最推荐方法是使用 Link 组件将用户重定向到包含相应语言环境的路由。这将利用 Next.js 的预取功能,并避免页面强制刷新。

        src/components/localeSwitcher/LocaleSwitcher.tsx
        "use client";import type { FC } from "react";import { Locales, getHTMLTextDir, getLocaleName } from "intlayer";import { useLocale } from "next-intlayer";export const LocaleSwitcher: FC = () => {  const { locale, availableLocales, setLocale } = useLocale();  return (    <div>      <button popoverTarget="localePopover">{getLocaleName(locale)}</button>      <div id="localePopover" popover="auto">        {availableLocales.map((localeItem) => (          <button            key={localeItem}            aria-current={locale === localeItem ? "page" : undefined}            onClick={() => setLocale(localeItem)}          >            <span>              {/* 语言环境 - 例如:ZH */}              {localeItem}            </span>            <span>              {/* 语言环境自身的名称 - 例如:中文 */}              {getLocaleName(localeItem, locale)}            </span>            <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>              {/* 当前语言环境下的名称 - 例如:Francés(当当前语言环境为 Locales.SPANISH 时) */}              {getLocaleName(localeItem)}            </span>            <span dir="ltr" lang={Locales.ENGLISH}>              {/* 英语下的名称 - 例如:Chinese */}              {getLocaleName(localeItem, Locales.ENGLISH)}            </span>          </button>        ))}      </div>    </div>  );};
        另一种方法是使用 useLocale 钩子提供的 setLocale 函数。该函数不支持页面预取。有关更多详细信息,请查看 useLocale 钩子文档
      10. 优化包体积

        可选

        使用 next-intlayer 时,字典默认会包含在每个页面的包中。为了优化包体积,Intlayer 提供了一个可选的 SWC 插件,它利用宏智能地优化 useIntlayer 调用。这确保了字典仅包含在实际使用它们的页面的包中。

        要启用此优化,请安装 @intlayer/swc 包。安装后,next-intlayer 会自动检测并使用该插件:

        bash
        npm install @intlayer/swc --save-dev
        注意:此优化仅适用于 Next.js 13 及以上版本。
        注意:由于 Next.js SWC 插件仍处于试验阶段,该包默认未安装。未来可能会有所改变。
        注意:如果您设置了 importMode: 'dynamic'importMode: 'fetch'(在字典配置中),它将依赖于 Suspense,因此您需要将 useIntlayer 调用包裹在 Suspense 边界内。这意味着您无法直接在页面/布局组件的顶层使用 useIntlayer
      11. 提取组件内容

        可选

        如果您有现有的代码库,转换数千个文件可能会非常耗时。

        为了简化此过程,Intlayer 提出了 编译器 / 提取器 来转换您的组件并提取内容。

        要进行设置,您可以在 intlayer.config.ts 文件中添加 compiler 部分:

        intlayer.config.ts
        import { type IntlayerConfig } from "intlayer";
        
        const config: IntlayerConfig = {
          // ... 您的其他配置
          compiler: {
            /**
             * 指示是否应启用编译器。
             */
            enabled: true,
        
            /**
             * 定义输出文件路径
             */
            output: ({ fileName, extension }) => `./${fileName}${extension}`,
        
            /**
             * 指示在转换后是否应保存组件。这样,编译器只需运行一次即可转换应用程序,然后即可将其删除。
             */
            saveComponents: false,
        
            /**
             * 字典键前缀
             */
            dictionaryKeyPrefix: "",
          },
        };
        
        export default config;

        运行提取器以转换组件并提取内容

        bash
        npx intlayer extract

    TypeScript 配置

    Intlayer 使用模块扩展 (module augmentation) 来利用 TypeScript 的优势并使您的代码库更加健壮。

    自动补全

    翻译错误

    确保您的 TypeScript 配置包含自动生成的类型。

    tsconfig.json
    {  // ... 您的现有 TypeScript 配置  "include": [    // ... 您的现有 TypeScript 配置    ".intlayer/**/*.ts", // 包含自动生成的类型  ],}

    Git 配置

    建议忽略 Intlayer 生成的文件。这可以避免将它们提交到您的 Git 存储库中。

    为此,您可以在 .gitignore 文件中添加以下指令:

    .gitignore
    # 忽略 Intlayer 生成的文件.intlayer

    VS Code 扩展

    为了提升使用 Intlayer 的开发体验,您可以安装官方 Intlayer VS Code 扩展

    从 VS Code Marketplace 安装

    该扩展提供:

    • 翻译键的自动补全
    • 缺失翻译的实时错误检测
    • 翻译内容的内联预览
    • 轻松创建和更新翻译的快速操作 (Quick actions)

    阅读 Intlayer VS Code 扩展文档 以了解更多关于扩展使用的详细说明。

    进一步深入

    您可以实现 可视化编辑器 或使用 CMS 来实现内容的外部管理。