logo
  • 指南
  • 配置
  • 插件
  • API
  • 示例
  • 社区
  • Modern.js 2.x 文档
  • 简体中文
    • 简体中文
    • English
    • 开始
      介绍
      快速上手
      版本升级
      名词解释
      技术栈
      核心概念
      页面入口
      构建工具
      Web 服务器
      基础功能
      路由
      路由基础
      配置式路由
      数据管理
      数据获取
      数据写入
      数据缓存
      渲染
      服务端渲染(SSR)
      服务端流式渲染(Streaming SSR)
      渲染缓存
      静态站点生成(SSG)
      渲染预处理 (Render Preprocessing)
      样式开发
      引入 CSS
      使用 CSS Modules
      使用 CSS-in-JS
      使用 Tailwind CSS
      HTML 模板
      引用静态资源
      引用 JSON 文件
      引用 SVG 资源
      引用 Wasm 资源
      调试
      数据模拟(Mock)
      网络代理
      使用 Rsdoctor
      使用 Storybook
      测试
      Playwright
      Vitest
      Jest
      Cypress
      路径别名
      环境变量
      构建产物目录
      部署应用
      进阶功能
      使用 Rspack
      使用 BFF
      基础用法
      运行时框架
      扩展 BFF Server
      扩展一体化调用 SDK
      文件上传
      跨项目调用
      优化页面性能
      代码分割
      静态资源内联
      产物体积优化
      React Compiler
      提升构建性能
      浏览器兼容性
      配置底层工具
      源码构建模式
      服务端监控
      Monitors
      日志事件
      指标事件
      国际化
      基础概念
      快速开始
      配置说明
      语言检测
      资源加载
      路由集成
      API 参考
      高级用法
      最佳实践
      自定义 Web Server
      专题详解
      模块联邦
      简介
      开始使用
      应用级别模块
      服务端渲染
      部署
      集成国际化能力
      常见问题
      依赖安装问题
      命令行问题
      构建相关问题
      热更新问题
      已下线功能
      📝 编辑此页面
      上一页国际化下一页快速开始

      #基础概念

      在项目集成国际化能力之前,需要了解国际化相关概念。理解核心概念可以帮助你快速建立稳定的翻译体系,帮助我们更好地解决使用过程中的各种问题。

      #核心概念

      #i18n

      i18n 是 Internationalization 的缩写,指让应用在不同语言、地区和文化中都能良好运行,需要在设计阶段就考虑多语言资源、数字/日期/货币以及文化差异等因素。

      #i18next

      i18next 是一个通用的国际化框架,提供语言检测、资源管理、插值、复数等能力。@modern-js/plugin-i18n 默认基于 i18next,请参考其官方文档获取完整的配置说明。

      #react-i18next

      react-i18next 是 i18next 的 React 绑定库,提供 useTranslation、Trans 等 Hook/组件,实现与 React 生命周期良好结合:

      import { useTranslation } from 'react-i18next';
      
      function App() {
        const { t } = useTranslation();
        return <h1>{t('welcome')}</h1>;
      }

      #i18n 实例

      i18next 默认导出一个实例,也支持通过 createInstance 生成多实例:

      import i18next, { createInstance } from 'i18next';
      
      i18next.init({
        /* ... */
      });
      
      const custom = createInstance();
      await custom.init({
        /* 独立配置 */
      });

      实例负责翻译资源、当前语言、切换语言等功能,也可以在 Modern.js 的 runtime 中传入自定义实例。

      #初始化(init)

      i18next 通过 init 完成初始化,常用核心选项:

      • lng:初始语言
      • ns / defaultNS:命名空间列表与默认命名空间
      • supportedLngs:允许的语言集合
      • fallbackLng:缺失资源时的回退语言(可为数组或映射)
      • interpolation:插值设置,React 环境通常配置 escapeValue: false
      i18next.init({
        lng: 'zh',
        ns: ['translation', 'common'],
        defaultNS: 'translation',
        supportedLngs: ['zh', 'en'],
        fallbackLng: ['en'],
        interpolation: { escapeValue: false },
      });

      #t 函数

      t 是获取翻译的核心 API,可直接从实例使用,也可以通过 react-i18next Hook 获得:

      i18next.t('welcome');
      const { t } = useTranslation();
      t('welcome', { name: 'Modern.js', count: 3 });

      t 支持插值、复数、上下文等高级特性,后文会展开说明。

      #语言代码

      语言代码用于标识当前界面语言,遵循 ISO 639-1 标准(en、zh 等),也可以携带地区信息(en-US、zh-CN)。

      • 支持语言列表:通过插件配置声明,编译期即可获知需要生成的产物。
      • 默认语言:当检测不到用户语言或资源缺失时使用。
      • 回退语言链:en-US → en → zh 这类链决定缺失翻译时的查找顺序。
      // modern.config.ts
      import { defineConfig } from '@modern-js/app-tools';
      import { i18nPlugin } from '@modern-js/plugin-i18n';
      
      export default defineConfig({
        plugins: [
          i18nPlugin({
            localeDetection: {
              languages: ['zh', 'en', 'ja'],
              fallbackLanguage: ['zh', 'en'], // 支持回退链
            },
          }),
        ],
      });

      💡 建议将 supportedLanguages 与 fallbackLanguage 同步维护,避免出现用户切换到未配置语言的情况。

      #命名空间

      命名空间(Namespace)用于按照业务模块拆分翻译文件,便于代码分割与按需加载。未指定时使用默认命名空间 translation。

      // src/modern.runtime.ts
      import { defineRuntimeConfig } from '@modern-js/runtime';
      
      export default defineRuntimeConfig({
        i18n: {
          initOptions: {
            ns: ['translation', 'common', 'dashboard'],
            defaultNS: 'translation',
          },
        },
      });

      在组件中使用不同命名空间:

      import { useTranslation } from 'react-i18next';
      
      export function DashboardHeader() {
        const { t } = useTranslation(['dashboard', 'common']);
        return (
          <header>
            <h1>{t('dashboard:title')}</h1>
            <button>{t('common:button.refresh')}</button>
          </header>
        );
      }

      命名空间还可以和动态加载结合,按需请求大体量文案。

      #资源文件结构

      推荐的资源文件目录:

      locales/
      ├── en/
      │   ├── translation.json
      │   ├── common.json
      │   └── dashboard.json
      └── zh/
          ├── translation.json
          ├── common.json
          └── dashboard.json
      • 文件命名:locales/<language>/<namespace>.json
      • 格式:标准 JSON,键值对或嵌套对象
      • 组织:嵌套对象用于表示 UI 层级,例如按钮、对话框等
      {
        "header": {
          "title": "欢迎",
          "actions": {
            "save": "保存",
            "cancel": "取消"
          }
        }
      }

      也可以通过 resources 选项在初始化时直接注入资源,或在运行时调用 addResourceBundle:

      i18next.init({
        resources: {
          en: {
            common: {
              welcome: 'Welcome',
            },
          },
          zh: {
            common: {
              welcome: '欢迎',
            },
          },
        },
      });
      
      i18next.addResourceBundle('en', 'home', { title: 'Home' });

      #翻译键

      翻译键(Translation Key)是访问翻译的路径,通常使用点号表示层级:common.button.submit。

      命名规范建议:

      • 使用语义化单词,避免缩写
      • 按模块划分前缀(dashboard.table.*)
      • 可使用 : 指定命名空间(common:button.submit)
      • 避免直接把完整中文文案当作键
      const { t } = useTranslation();
      
      button.textContent = t('common.button.submit', {
        defaultValue: 'Submit',
      });

      #插值和变量

      插值(Interpolation)允许在翻译文本中动态注入变量。

      资源文件:

      {
        "welcome": "欢迎,{{name}}!",
        "invite": "{{name}} 邀请你加入 {{project}}",
        "formattedValue": "当前价格:{{value, currency}}"
      }

      用法:

      const { t } = useTranslation();
      
      return (
        <>
          <p>{t('welcome', { name: 'John' })}</p>
          <p>{t('invite', { name: 'Alice', project: 'Modern.js' })}</p>
        </>
      );

      #嵌套插值

      可以直接传递对象或多级变量:

      {
        "greeting": "你好,{{user.name}},你有 {{user.notifications}} 条新消息"
      }
      t('greeting', {
        user: { name: 'Jay', notifications: 3 },
      });

      #格式化插值

      通过 interpolation.format 函数格式化数字、日期等:

      export default defineRuntimeConfig({
        i18n: {
          initOptions: {
            interpolation: {
              format(value, format, lng) {
                if (format === 'currency') {
                  return new Intl.NumberFormat(lng, {
                    style: 'currency',
                    currency: lng === 'zh' ? 'CNY' : 'USD',
                  }).format(Number(value));
                }
                if (value instanceof Date) {
                  return new Intl.DateTimeFormat(lng, { dateStyle: 'medium' }).format(
                    value,
                  );
                }
                return value;
              },
            },
          },
        },
      });
      t('formattedValue', { value: 99.5, format: 'currency' });

      #转义插值

      react-i18next 默认会对插值值进行转义以防止 XSS。如需渲染安全的 HTML,需显式开启 interpolation.escapeValue = false 并确保数据可信。

      #复数

      复数处理根据语言自动选择合适的词形,依赖 count 参数。

      {
        "item": "1 个条目",
        "item_plural": "{{count}} 个条目",
        "item_0": "没有条目"
      }
      t('item', { count: 0 }); // 没有条目
      t('item', { count: 1 }); // 1 个条目
      t('item', { count: 5 }); // 5 个条目

      不同语言具有不同的复数规则,例如:

      • 英语:单数、复数
      • 俄语:one、few、many 多种形式
      • 中文:通常只有单一形式,可使用 _0 键覆盖特殊文案

      💡 如果需要自定义复数规则,可通过 i18next.services.pluralResolver 扩展,详见高级用法。

      #嵌套翻译结构

      嵌套结构可以直观反映 UI 层级。

      {
        "common": {
          "button": {
            "submit": "提交",
            "cancel": "取消"
          }
        }
      }

      在代码中使用点号访问:

      const { t } = useTranslation();
      t('common.button.submit');

      嵌套结构的优势:

      • 避免键名冗长
      • 便于在 JSON 中整体查看模块文案
      • 可搭配 keyPrefix 精简调用:useTranslation('common', { keyPrefix: 'button' })

      #回退语言

      当当前语言缺少某个键时,会按回退语言链继续查找。

      export default defineRuntimeConfig({
        i18n: {
          initOptions: {
            lng: 'zh-CN',
            fallbackLng: {
              'zh-CN': ['zh', 'en'],
              default: ['en'],
            },
          },
        },
      });
      Tip

      可以将地区语言(如 zh-CN)回退到通用语言(zh),最后再回退到默认语言(en),确保所有键都有可用文本。

      #语言检测

      i18next 通过语言检测插件自动识别用户语言,Modern.js 插件内置浏览器与服务端支持。

      import LanguageDetector from 'i18next-browser-languagedetector';
      import i18next from 'i18next';
      
      i18next.use(LanguageDetector).init({
        supportedLngs: ['zh', 'en', 'ja'],
        detection: {
          order: ['path', 'cookie', 'localStorage', 'navigator'],
          lookupCookie: 'i18next',
          lookupLocalStorage: 'i18nextLng',
        },
      });

      Modern.js 中可以直接在插件配置里开启内置检测:

      i18nPlugin({
        localeDetection: {
          i18nextDetector: true,
          languages: ['zh', 'en'],
          detection: {
            order: ['path', 'cookie', 'header'],
          },
        },
      });
      Warning

      启用检测后,无需在 init 中显式设置 lng。如果手动调用 changeLanguage() 未传入语言,也会根据检测配置自动推断。