首页演练场案例展示应用文档博客
    • English英语
      EN
    • русский俄语
      RU
    • 日本語日语
      JA
    • français法语
      FR
    • 한국어韩语
      KO
    • 中文中文
      ZH
    • español西班牙语
      ES
    • Deutsch德语
      DE
    • العربية阿拉伯语
      AR
    • italiano意大利语
      IT
    • British English英国英语
      EN-GB
    • português葡萄牙语
      PT
    • हिन्दी印地语
      HI
    • Türkçe土耳其语
      TR
    • polski波兰语
      PL
    • Indonesia印度尼西亚语
      ID
    • Tiếng Việt越南语
      VI
    • українська乌克兰语
      UK
    /
    按框架筛选文档
    Alt+←
    为什么Intlayer?
    开始
    概念
    • Intlayer如何工作
    • 配置
    • TestFillBuildWatchExtractLoginPushPullConfigurationListVersionEditorLiveDebugDoc ReviewDoc TranslateSDK
    • 可视化编辑器
    • CMS
    • CI/CD集成
    • 翻译复数枚举条件性别插入文件嵌套MarkdownHTML函数获取
    • 每个语言环境的文件
    • 编译器
    • 自动填充
    • 测试
    • 打包优化
    环境
    • Next.js 14和应用路由器
      Next.js 15
      Next.js 无 locale URL
      Next.js和页面路由器
      编译器
    • Tanstack Start Solid
    • Astro和React
      Astro和Svelte
      Astro和Vue
      Astro和Solid
      Astro和Preact
      Astro和Lit
      Astro和Vanilla JS
    • React Router v7
      React Router v7 (fs-routes)
      Compiler
    • Nuxt和Vue
    • Vite和Solid
    • SvelteKit
    • Vite和Preact
    • Vite和Vanilla JS
    • Vite和Lit
    • Angular 19 (Webpack)
      Analog
    • React CRA
    • React Native和Expo
    • Express.js
      NestJS
      Fastify
      Hono
      Adonis
    • Lynx和React
    Plugins
    • JSON
    • gettext (.po)
    VS Code扩展
    代理
    • MCP服务器
    • 代理技能
    发布
    • v8
    • v7
    • v6
    基准测试
    • Next.js
    • TanStack
    • Vue
    • Solid
    • Svelte
    博客
    问问题
    1. Documentation
    2. 环境
    3. Next.js
    4. Compiler
    Creation:2026-01-10Last update:2026-05-06
    在 GitHub 上查看应用程序模板

    此页面有可用的应用程序模板。

    观看视频教程

    此页面有视频教程。

    将此文档参考到您的 AI 助手
    ChatGPT
    Claude
    DeepSeek
    Google AI mode
    Gemini
    Perplexity
    Mistral
    Grok

    使用您最喜欢的AI助手总结文档,并引用此页面和AI提供商

    版本历史

    1. "更新 Solid useIntlayer API 用法以直接访问属性"
      v8.9.02026/5/4
    2. "Update compiler options, add FilePathPattern support"
      v8.2.02026/3/9
    3. "初始版本"
      v8.1.62026/2/23

    此页面的内容已使用 AI 翻译。

    查看英文原文的最新版本
    编辑此文档

    如果您有改善此文档的想法,请随时通过在GitHub上提交拉取请求来贡献。

    文档的 GitHub 链接
    Copy

    复制文档 Markdown 到剪贴板

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

    www.youtube.com
    ide.intlayer.org

    在 GitHub 上查看应用程序模板。

    目录

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

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

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

    什么是 Intlayer 编译器?

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

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

    限制

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

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


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

    步骤 1:安装依赖项

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

    bash
    复制代码

    复制代码到剪贴板

    npm install intlayer next-intlayernpm install @intlayer/babel --save-devnpx intlayer init
    • intlayer

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

    • next-intlayer

      将 Intlayer 与 Next.js 集成的包。它为 Next.js 国际化提供上下文提供程序和钩子。此外,它还包括用于将 Intlayer 与 Webpack 或 Turbopack 集成的 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 集成。它确保字典文件的构建,并在开发模式下监视它们。它在 Webpack 或 Turbopack 环境中定义 Intlayer 环境变量。此外,它还提供别名以优化性能,并保留与服务器组件的兼容性。

    配置 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()],  ],};

    步骤 4:页面中的语言环境检测

    清空 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;

    步骤 5:声明您的内容(自动)

    启用编译器后,您不再需要手动声明内容字典(例如 .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>);}
    i18n/page-content.content.tsx
    复制代码

    复制代码到剪贴板

    {key: "page-content",content: {  nodeType: "translation",  translation: {    en: {      getStartedByEditingThis: "Get started by editing this!",    },    fr: {      getStartedByEditingThis: "Commencez par éditer ceci !",    },    zh: {      getStartedByEditingThis: "开始编辑吧!",    },  }}}
    src/app/page.tsx
    复制代码

    复制代码到剪贴板

    import { type FC } from "react";import { IntlayerServerProvider, useIntlayer } from "next-intlayer/server";import { getLocale } from "next-intlayer/server";const PageContent: FC = () => {const content = useIntlayer("page-content");return (  <>    <p>{content.getStartedByEditingThis}</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。

    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 扩展文档 以了解更多关于扩展使用的详细说明。

    (可选) 步骤 1 : 提取组件内容

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

    为了简化此过程,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
    bash
    复制代码

    复制代码到剪贴板

    npm install @intlayer/babel --save-dev
    babel.config.js
    复制代码

    复制代码到剪贴板

    const { intlayerExtractBabelPlugin, getExtractPluginOptions,} = require("@intlayer/babel");module.exports = { presets: ["next/babel"], plugins: [   // 将组件内容提取到字典中   [intlayerExtractBabelPlugin, getExtractPluginOptions()], ],};
    bash
    复制代码

    复制代码到剪贴板

    npm run build # 或 npm run dev

    进一步深入

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

    Next.js和页面路由器
    Tanstack Start
    Alt+→

    在此页面

      讨论是匿名的,并会定期审查以解决常见问题。欢迎分享功能想法、对文档的反馈或任何与 Intlayer 相关的内容, 我们会利用这些意见来制定路线图并改进产品。

      npm install intlayer next-intlayernpm install @intlayer/babel --save-devnpx intlayer init
      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;
      import type { NextConfig } from "next";import { withIntlayer } from "next-intlayer/server";const nextConfig: NextConfig = {  /* 这里可选填写额外的 Next.js 配置 */};export default withIntlayer(nextConfig);
      const {  intlayerExtractBabelPlugin,  intlayerOptimizeBabelPlugin,  getExtractPluginOptions,  getOptimizePluginOptions,} = require("@intlayer/babel");module.exports = {  presets: ["next/babel"],  plugins: [    [intlayerExtractBabelPlugin, getExtractPluginOptions()],    [intlayerOptimizeBabelPlugin, getOptimizePluginOptions()],  ],};
      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;
      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>);}
      {key: "page-content",content: {  nodeType: "translation",  translation: {    en: {      getStartedByEditingThis: "Get started by editing this!",    },    fr: {      getStartedByEditingThis: "Commencez par éditer ceci !",    },    zh: {      getStartedByEditingThis: "开始编辑吧!",    },  }}}
      import { type FC } from "react";import { IntlayerServerProvider, useIntlayer } from "next-intlayer/server";import { getLocale } from "next-intlayer/server";const PageContent: FC = () => {const content = useIntlayer("page-content");return (  <>    <p>{content.getStartedByEditingThis}</p>    <code>src/app/page.tsx</code>  </>);};export default async function Page() {const locale = await getLocale();return (  <IntlayerServerProvider locale={locale}>    <PageContent />  </IntlayerServerProvider>);}
      npx intlayer test         # 测试是否有缺失的翻译
      npx intlayer fill         # 填写缺失的翻译
      export { intlayerProxy as proxy } from "next-intlayer/proxy";export const config = {  matcher:    "/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",};
      "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>  );};
      npm install @intlayer/swc --save-dev
      {  // ... 您的现有 TypeScript 配置  "include": [    // ... 您的现有 TypeScript 配置    ".intlayer/**/*.ts", // 包含自动生成的类型  ],}
      # 忽略 Intlayer 生成的文件.intlayer
      npx intlayer extract
      npm install @intlayer/babel --save-dev
      const { intlayerExtractBabelPlugin, getExtractPluginOptions,} = require("@intlayer/babel");module.exports = { presets: ["next/babel"], plugins: [   // 将组件内容提取到字典中   [intlayerExtractBabelPlugin, getExtractPluginOptions()], ],};
      npm run build # 或 npm run dev