01MVP 标识01MVP
开发指南国际化策略

国际化策略

Monorepo 下的共享翻译与应用覆盖策略

本页面介绍 Monorepo 国际化策略和配置。API 使用详情请参考 包文档

概览

项目使用 next-intl,并采用「共享翻译 + 应用覆盖」两层模型,适配 monorepo 多项目场景。

目录结构

packages/i18n/
├── src/messages.ts                      # 核心加载与合并逻辑
└── translations/shared/
    ├── en.json                          # 共享英文翻译
    └── zh.json                          # 共享中文翻译

apps/mono-web/src/modules/i18n/
├── messages.ts                          # mono-web 的 i18n 入口(调用 @mono/i18n)
└── translations/
    ├── en.json                          # mono-web 私有覆盖
    └── zh.json                          # mono-web 私有覆盖

合并与优先级

请求语言为 locale 时,最终消息按以下顺序合并(后者覆盖前者):

  1. shared/defaultLocale
  2. shared/locale
  3. app/defaultLocale
  4. app/locale

缺失 key 会走 next-intlgetMessageFallback,回退到 key 本身,不会中断页面渲染。

Key 规范

使用嵌套对象,不使用扁平化 key。按业务域分组:

{
	"auth": {
		"login": {
			"title": "登录"
		}
	},
	"documentation": {
		"title": "文档"
	}
}

组件调用示例:

import { useTranslations } from "next-intl";

function MyComponent() {
	const t = useTranslations("documentation");
	return <p>{t("title")}</p>;
}

新增翻译流程

  1. 先在 shared/en.json(defaultLocale)增加新 key。
  2. 再补 shared/zh.json
  3. 如果某个项目文案需要特殊化,仅在该项目的 apps/<app>/src/modules/i18n/translations/*.json 覆盖对应节点。
  4. 不要在 app 层重复复制 shared 全量文案,只维护差异。

适用策略(多项目)

  1. 多项目共用的 UI 文案放 packages/i18n/translations/shared
  2. 项目品牌词、业务术语、A/B 文案放各自 app 的 translations
  3. 新项目接入时只需新增 apps/<new-app>/src/modules/i18n/messages.ts 与两份 locale 覆盖文件。

MDX 文档国际化

content/docs/
├── page.zh.mdx
└── page.en.mdx

Fumadocs 会根据当前 locale 自动选择对应文档版本。

校验命令(与代码同步)

apps/mono-web 下执行:

pnpm i18n:check

严格模式(CI 推荐):

pnpm i18n:check:strict

校验规则

i18n:check

  1. 扫描 apps/mono-web/srcpackages/ui/srcuseTranslations/getTranslations 实际使用到的 key。
  2. 检查每个 locale 的最终合并结果(shared + app override)是否缺失这些代码实际使用 key。
  3. 仅当“代码在用但 locale 缺失”时失败。

i18n:check:strict

  1. 包含 i18n:check 全部规则。
  2. 额外要求每个 locale 与默认参考 key 集(en 合并结果)一致。
  3. 出现 missing 或 extra key 都会失败(适合 CI 门禁)。

推荐工作流

  1. 本地开发时先跑 pnpm i18n:check,保证不会线上缺词。
  2. 提交前或 CI 跑 pnpm i18n:check:strict,防止 key 漂移。
  3. 发现缺失后优先补 shared/en.json,再补 shared/zh.json,最后按需在 app 层覆盖。