Skip to content

网站国际化(i18n)指南

目标:本文档是添加新语言的完整操作手册。下次添加韩语(ko)、法语(fr)等语言时,请严格按照本文档的步骤操作。

当前已支持:英语(en)、中文(zh)、日语(ja)、西班牙语(es)、葡萄牙语(pt


目录

  1. 系统架构
  2. 添加新语言:分步操作指南
  3. 国际化模式参考
  4. CSS 语言切换机制
  5. L() 辅助函数
  6. 配置文件(config.mts)
  7. 页面文件结构
  8. 文件清单
  9. 附录:日语支持时间线

1. 系统架构

.vitepress/
├── theme/
│   ├── utils/
│   │   └── i18n.ts          ← 核心国际化模块(翻译数据 + useI18n hook)
│   ├── components/
│   │   ├── **/*.vue          ← 各组件中通过 t() / L() / .en.zh.ja 使用翻译
│   │   └── ...
│   └── custom.css            ← 全局 .lang-xx 等语言选择器 CSS
├── config.mts                ← VitePress 配置(locales、导航、侧边栏、语言检测脚本)
└── ...

zh/                           ← 中文页面文件(markdown)
ja/                           ← 日语页面文件(markdown)

核心模块:i18n.ts

文件位置:.vitepress/theme/utils/i18n.ts

导出:

  • messages 对象:包含 enzhja 三个语言的翻译数据
  • useI18n() hook:返回 tlanglocaleisChineseisJapaneselocalePath
ts
const { t, lang, locale, isChinese, isJapanese, localePath } = useI18n()

t('auth.login')              // 根据当前语言返回翻译文本
localePath('/home')          // 生成正确的语言路径(如 /ja/home)
isChinese.value              // 是否中文
isJapanese.value             // 是否日语

2. 添加新语言:分步操作指南

假设要添加韩语(ko。以下步骤需按顺序执行,每步完成后请对照自查清单打勾 ✅。

第 1 步:翻译数据(i18n.ts

文件.vitepress/theme/utils/i18n.ts

  • [ ] 在 messages 对象中添加 ko 区块
  • [ ] 复制 en 的所有 key 结构,替换为韩语翻译
  • [ ] 确保 key 路径与 en 完全一致(层级和数量)
ts
const messages = {
  en: { /* ... */ },
  zh: { /* ... */ },
  ja: { /* ... */ },
  ko: {  // ← 新增
    auth: {
      login: '로그인',
      logout: '로그아웃',
      signInWithGoogle: 'Google로 로그인',
    },
    common: {
      cancel: '취소',
      save: '저장',
    },
    // ... 所有 key
  },
}

第 2 步:更新 useI18n() hook

文件.vitepress/theme/utils/i18n.ts

  • [ ] locale computed 中添加语种检测
  • [ ] 添加 isKorean computed(或其他新语言标识)
  • [ ] 更新 localePath() 路径前缀逻辑
ts
const locale = computed(() => {
  const l = (lang.value || 'en').toLowerCase()
  if (l.startsWith('zh')) return 'zh'
  if (l.startsWith('ja')) return 'ja'
  if (l.startsWith('ko')) return 'ko'  // ← 新增
  return 'en'
})

const isChinese = computed(() => locale.value === 'zh')
const isJapanese = computed(() => locale.value === 'ja')
const isKorean = computed(() => locale.value === 'ko')  // ← 新增

// localePath 需处理新语言前缀
const localePath = (path) => {
  const prefix = l === 'zh' ? '/zh' : l === 'ja' ? '/ja' : l === 'ko' ? '/ko' : ''
  return prefix + path
}

第 3 步:全局 CSS 支持

文件.vitepress/theme/custom.css

  • [ ] 添加新语言的全局 CSS 规则
css
/* 韩语模式全局规则 */
.ko { display: none; }
.lang-ko .ko { display: revert; }
.lang-ko .en { display: none; }
.lang-ko .zh { display: none !important; }
.lang-ko .ja { display: none !important; }

⚠️ 重要.lang-ko .en 必须设为 display: none(而非 revert),否则多语言会同时显示。

第 4 步:配置文件(config.mts

文件.vitepress/config.mts

  • [ ] locales 中添加新语言条目
  • [ ] 为该语言配置导航栏(themeConfig.nav
  • [ ] 为该语言配置侧边栏(themeConfig.sidebar
  • [ ] 更新内联语言检测脚本
ts
locales: {
  root: { label: 'English', lang: 'en', link: '/' },
  zh: { label: '简体中文', lang: 'zh', link: '/zh/' },
  ja: { label: '日本語', lang: 'ja', link: '/ja/' },
  ko: { label: '한국어', lang: 'ko', link: '/ko/' },  // ← 新增
}

语言检测脚本更新:

js
var browserLang = (navigator.language || 'en').toLowerCase();
targetLang = browserLang.indexOf('zh') !== -1 ? 'zh' 
           : browserLang.indexOf('ja') !== -1 ? 'ja'
           : browserLang.indexOf('ko') !== -1 ? 'ko'  // ← 新增
           : 'en';

⚠️ 导航栏中的外部链接(如 FastMoss 主站)也需按语言调整。

第 5 步:创建页面文件

  • [ ] 创建 ko/ 目录,目录结构与 ja/ 保持一致
  • [ ] 复制 ja/ 的所有 .md 文件到 ko/
  • [ ] 翻译每个 .md 文件的内容
  • [ ] 检查 frontmatter(如 titledescription)是否需要翻译

多数页面仅引用 Vue 组件(文本由 t() 或 span 处理),但 API 文档页面含有具体内容,需要逐页翻译。

第 6 步:更新 Vue 组件(核心工作量)

这是最繁琐的一步。需要遍历所有组件,根据其国际化模式做对应修改。

6a. 处理模式 B 组件(<span class="en/zh/ja">

搜索所有使用了 .en / .zh / .ja span 的组件,见「文件清单」章节:

vue
<!-- ✅ 为每个 .ja span 后面添加 .ko span -->
<h1>
  <span class="en">Get Help</span>
  <span class="zh">获取帮助</span>
  <span class="ja">ヘルプを見る</span>
  <span class="ko">도움말 보기</span>    <!-- ← 新增 -->
</h1>

在组件 scoped CSS 中添加 .ko / .lang-ko 规则。参考下方「CSS 语言切换机制」章节。

6b. 处理模式 C 组件(v-if="isChinese"

搜索所有使用 isChinese / isJapanese 的组件:

vue
<!-- ✅ 添加新语言分支 -->
<h1 v-if="isChinese">中文</h1>
<h1 v-else-if="isJapanese">日本語</h1>
<h1 v-else-if="isKorean">한국어</h1>    <!-- ← 新增 -->
<h1 v-else>English</h1>

⚠️ 注意 v-if="!isChinese"v-if="isChinese || isJapanese" 这类条件逻辑——新语言可能属于哪个组别需要单独判断。

6c. 处理组件根元素 class 绑定

确保每个组件的根元素有完整绑定:

vue
<div :class="{ 'lang-zh': isChinese, 'lang-ja': isJapanese, 'lang-ko': isKorean }">

6d. 处理数据驱动组件(L() 函数)

搜索使用 L() 函数的组件(见文件清单),更新函数和数据:

ts
// L() 函数增加第 4 参数
const L = (en, zh, ja, ko) => isChinese.value ? zh 
       : (isJapanese.value ? (ja || en) 
       : (isKorean.value ? (ko || en) : en))

// 数据增加 Ko 后缀字段
const items = [
  {
    title: 'Find a product opportunity',
    titleZh: '选品:找值得做的机会',
    titleJa: '商品機会を見つける',
    titleKo: '제품 기회 찾기',         // ← 新增
  }
]

6e. 处理 copyText / copyPrompt 等反馈函数

js
// 复制反馈增加韩语
const en = el.querySelector('.en'), zh = el.querySelector('.zh'), 
      ja = el.querySelector('.ja'), ko = el.querySelector('.ko')
if (en && zh && ja && ko) {
  const origEn = en.textContent, origZh = zh.textContent, 
        origJa = ja.textContent, origKo = ko.textContent
  en.textContent = 'Copied'; zh.textContent = '已复制'; 
  ja.textContent = 'コピーしました'; ko.textContent = '복사됨'
  setTimeout(() => {
    en.textContent = origEn; zh.textContent = origZh
    ja.textContent = origJa; ko.textContent = origKo
  }, 1400)
}

6f. 处理 ROLE_LABEL 等映射数组

js
const ROLE_LABEL = {
  context: ['Context', '背景', 'コンテキスト', '컨텍스트'],  // ← 新增
}
// 取值逻辑更新
const idx = isChinese.value ? 1 : (isJapanese.value ? 2 : (isKorean.value ? 3 : 0))
const label = ROLE_LABEL[r][idx]

6g. 处理 promptOutput computed 等条件分支

js
if (zh) {
  // 中文 prompt
} else if (ja) {
  // 日语 prompt
} else if (ko) {
  // 韩语 prompt(新增分支)
} else {
  // 英语 prompt
}

第 7 步:验证构建

bash
npm run docs:build
  • [ ] 无编译错误
  • [ ] 首页 / 正常显示
  • [ ] /ko/ 页面正常显示
  • [ ] 语言切换器显示新语言
  • [ ] 导航栏链接正确
  • [ ] 侧边栏正确显示
  • [ ] 搜索功能正常
  • [ ] 登录/注册页面正常
  • [ ] 切换语言后所有文本正确显示

3. 国际化模式参考

项目中存在三种国际化渲染模式,新语言需要全部覆盖。

模式 A:t() 函数(推荐)

适用于纯文本、按钮、标签等。

vue
<button>{{ t('auth.login') }}</button>
<p>{{ t('common.loading') }}</p>

新语言适配:只需在 messages 中添加对应语言的翻译 key。

模式 B:.en / .zh / .ja span + CSS 切换

适用于带有复杂 HTML 结构或需要语法高亮的文本块。

vue
<h1>
  <span class="en">TikTok Shop data,<br><em>every way you work</em></span>
  <span class="zh">TikTok Shop数据,<br>融入你的每种工作方式</span>
  <span class="ja">TikTok Shopデータ、<br><em>あらゆる作業方法に対応</em></span>
</h1>

新语言适配:为每一对 .en/.zh/.ja 添加对应的新语言 span,并添加 CSS 规则。

⚠️ 注意语序差异:不同语言的语序可能不同,高亮部分(<em> 或渐变文字)需要根据目标语法重新组织,不能逐字翻译。

模式 C:v-if / v-else-if / v-else 条件渲染

适用于整个段落或复杂 DOM 结构根据不同语言完全不同的场景。

vue
<h1 v-if="isChinese">中文标题</h1>
<h1 v-else-if="isJapanese">日本語のタイトル</h1>
<h1 v-else>English Title</h1>

新语言适配:在 v-if 链的适当位置插入新语言分支。


4. CSS 语言切换机制

全局 CSS(custom.css)

css
/* 韩语模式全局规则 — 添加新语言时复制此模板 */
.ko { display: none; }
.lang-ko .ko { display: revert; }
.lang-ko .en { display: none; }
.lang-ko .zh { display: none !important; }
.lang-ko .ja { display: none !important; }

组件级 CSS

每个使用模式 B(span)的组件都需要在自己的 <style scoped> 中添加规则:

css
/* 默认隐藏所有非英语语言 */
.my-class .zh { display: none; }
.my-class .ja { display: none; }
.my-class .ko { display: none; }

/* 各语言模式 */
.my-class.lang-zh .zh { display: revert; }
.my-class.lang-zh .en { display: none; }
.my-class.lang-zh .ja { display: none !important; }
.my-class.lang-zh .ko { display: none !important; }

.my-class.lang-ja .ja { display: revert; }
.my-class.lang-ja .en { display: none; }
.my-class.lang-ja .zh { display: none !important; }
.my-class.lang-ja .ko { display: none !important; }

.my-class.lang-ko .ko { display: revert; }   /* ← 新增 */
.my-class.lang-ko .en { display: none; }
.my-class.lang-ko .zh { display: none !important; }
.my-class.lang-ko .ja { display: none !important; }

组件绑定

每个组件的根元素必须有 class 绑定:

vue
<div class="my-component" :class="{ 'lang-zh': isChinese, 'lang-ja': isJapanese, 'lang-ko': isKorean }">

5. L() 辅助函数

定义(4 参数版本,用于韩语)

ts
const L = (en, zh, ja, ko) => isChinese.value ? zh 
       : (isJapanese.value ? (ja || en) 
       : (isKorean.value ? (ko || en) : en))

使用方式

vue
<!-- 传入对应语言的文本 -->
<h2>{{ L(current.title, current.titleZh, current.titleJa, current.titleKo) }}</h2>
<p>{{ L(current.sub, current.subZh, current.subJa, current.subKo) }}</p>

数据格式

ts
const items = [
  {
    title: 'Find a product opportunity',
    titleZh: '选品:找值得做的机会',
    titleJa: '商品機会を見つける',
    titleKo: '제품 기회 찾기',    // ← 新增
    sub: 'Judge demand, stage, competition, and entry timing.',
    subZh: '判断需求、所处阶段、竞争与进入时机。',
    subJa: '需要、段階、競争、参入タイミングを判断します。',
    subKo: '수요, 단계, 경쟁, 진입 시기를 판단합니다.',
    // ...
  }
]

常见陷阱

问题表现解决方案
L() 只有 2 参数日语/韩语用户看到英语升级为多参数版本
数组字段不一致索引错位或 undefined确保 getJa[] / getKo[]get[] 长度和顺序一致
静态 <span>L() 混淆内容结构错误<span> 用于静态标签,L() 用于动态数据文本

6. 配置文件(config.mts)

locales 配置

ts
locales: {
  root: { label: 'English', lang: 'en', link: '/' },
  zh: { label: '简体中文', lang: 'zh', link: '/zh/' },
  ja: { label: '日本語', lang: 'ja', link: '/ja/' },
  ko: { label: '한국어', lang: 'ko', link: '/ko/' },  // 新增
}

URL 路径规则

语言路径前缀示例
英文/(无前缀)/home.html
中文/zh//zh/home.html
日语/ja//ja/home.html
韩语/ko//ko/home.html

侧边栏配置

ts
sidebar: {
  '/api/docs/': [ /* 英文侧边栏 */ ],
  '/zh/api/docs/': [ /* 中文侧边栏 */ ],
  '/ja/api/docs/': [ /* 日语侧边栏 */ ],
  '/ko/api/docs/': [ /* 韩语侧边栏 */ ],  // 新增
}

7. 页面文件结构

每种语言有一套独立的 markdown 页面文件。新语言需要创建与 ja/ 完全相同的目录结构。

ko/                           ← 韩语页面(与 ja/ 结构一致)
├── index.md
├── home.md
├── login.md
├── register.md
├── pricing.md
├── checkout.md
├── api/
│   ├── overview.md
│   ├── pricing.md
│   └── docs/guide/quickStart.md
├── docs/
│   └── mcp/setup.md
├── mcp/
│   ├── overview.md
│   ├── pricing.md
│   └── setup.md
└── profile/
    ├── index.md
    └── ...

大多数页面仅引用 Vue 组件(文本由 t() 或 span 处理),但 API 文档页面含有具体内容,需要逐页翻译。


8. 文件清单

必须修改的核心文件

文件操作
.vitepress/theme/utils/i18n.ts添加翻译数据、更新 useI18n()、更新 localePath()
.vitepress/config.mts添加 locale 配置、导航、侧边栏、语言检测脚本
.vitepress/theme/custom.css添加 .lang-ko 全局 CSS 规则

需要添加语言 class 和 CSS 的组件(模式 B span)

以下组件使用了 <span class="en/zh/ja">,需要为每个 .ja 添加 .ko

#组件文件路径
1Authcomponents/Auth.vue
2SearchInSidebarcomponents/SearchInSidebar.vue
3DocSearchcomponents/docs/DocSearch.vue
4HomePagecomponents/HomePage.vue
5McpOverviewV2components/mcp/McpOverviewV2.vue
6AppFootercomponents/AppFooter.vue
7ApiOverviewcomponents/api/ApiOverview.vue
8McpPricingV2components/mcp/McpPricingV2.vue
9PricingByEndpointscomponents/api/PricingByEndpoints.vue
10DocsHomecomponents/docs/DocsHome.vue
11DocsSidebarcomponents/docs/DocsSidebar.vue
12CommunitySupportcomponents/docs/CommunitySupport.vue
13McpGuideSetupcomponents/docs/mcp/McpGuideSetup.vue
14McpGuideUnderstandcomponents/docs/mcp/McpGuideUnderstand.vue
15McpGuideHelpcomponents/docs/mcp/McpGuideHelp.vue
16ProfileSidebarcomponents/profile/ProfileSidebar.vue
17Dashboardcomponents/profile/Dashboard.vue
18OrderHistorycomponents/profile/OrderHistory.vue
19api/OrderHistorycomponents/profile/api/OrderHistory.vue
20api/Usagecomponents/profile/api/Usage.vue
21InvoiceApplycomponents/profile/InvoiceApply.vue
22api/InvoiceApplycomponents/profile/api/InvoiceApply.vue
23ReceiptListcomponents/profile/ReceiptList.vue
24api/ReceiptListcomponents/profile/api/ReceiptList.vue
25McpBillingcomponents/profile/mcp/McpBilling.vue
26McpApiKeyscomponents/profile/mcp/McpApiKeys.vue
27McpUsagecomponents/profile/mcp/McpUsage.vue
28McpInvoiceApplycomponents/profile/mcp/McpInvoiceApply.vue
29McpReceiptListcomponents/profile/mcp/McpReceiptList.vue
30FloatingDocActioncomponents/api/FloatingDocAction.vue
31DocButtonscomponents/api/DocButtons.vue
32CheckoutByTimecomponents/api/CheckoutByTime.vue
33Profilecomponents/Profile.vue
34OauthGoogleCallbackcomponents/OauthGoogleCallback.vue

提示:可通过 grep -r 'span class=\"ja\"' components/ 快速定位所有需要添加 .ko span 的文件。

需要处理 L() 函数和数据的数据驱动组件

组件文件需要更新
McpGuideSetupcomponents/docs/mcp/McpGuideSetup.vueL() → 4 参数 + 数据 Ko 字段
McpGuidePlaybookscomponents/docs/mcp/McpGuidePlaybooks.vueL() → 4 参数 + titleKo/subKo/getKo[]/promptKo/followupsKo[]
McpGuidePromptcomponents/docs/mcp/McpGuidePrompt.vueL() → 4 参数 + 映射韩语 + promptOutput 韩语分支 + ROLE_LABEL 第 4 项
McpGuideHelpcomponents/docs/mcp/McpGuideHelp.vueL() → 4 参数 + helpItems 每条加 Ko 字段

9. 附录:日语支持时间线

日期操作
2026-07-13添加 ja 翻译区块、更新 useI18n()、更新 config.mts
2026-07-13创建 ja/ 目录及页面文件
2026-07-13修复硬编码文本、更新语言检测逻辑
2026-07-13为 HomePage、McpOverviewV2 等核心组件添加日语内容
2026-07-13为文档组件添加日语支持
2026-07-13修复 CSS/日语显示问题
2026-07-13整理本文档

10. 多语言扩展:西班牙语(es)与葡萄牙语(pt)

本节记录 2026-08-28 为项目新增 es / pt 时实际执行的操作,作为后续新增语言(kofr 等)的直接模板。

10.1 新增语言涉及的核心文件

文件操作
.vitepress/theme/utils/i18n.tsuseI18n() 增加语言识别、localePath 前缀、isXxx computed;t() 对未翻译语言回退英文
.vitepress/config.mtsSITE_METALOCALESlocaleOfPage/stripLocaleOfPage、语言检测脚本 supportedLocalePrefixeslocales 条目(含导航)
.vitepress/theme/custom.css全局 .lang-es / .lang-pt 规则
es/pt/ 目录页面文件(英文骨架,后续逐页翻译)
docs/i18n-guide.md本文档(更新支持列表、追加扩展说明)

10.2 语言识别与路径(i18n.ts)

ts
const localeOf = (l: string) => {
  const s = (l || 'en').toLowerCase()
  if (s.startsWith('zh')) return 'zh'
  if (s.startsWith('ja')) return 'ja'
  if (s.startsWith('es')) return 'es'
  if (s.startsWith('pt')) return 'pt'
  return 'en'
}
  • t()messages[locale] 不存在时回退 messages.en避免新语言页面出现 path 占位符
  • localePath() 新增前缀分支:es → /espt → /pt

⚠️ 重要:未翻译语言(es/pt)的 t() 目前返回英文。若需完整翻译,请在 messages 中添加 es / pt 区块(复制 en 的 key 结构)。

10.3 config.mts 需要同步的点

  1. SITE_META[es] / SITE_META[pt](SEO title/desc)
  2. LOCALES = ['en', 'zh', 'ja', 'es', 'pt']
  3. localeOfPage() / stripLocaleOfPage() 增加前缀
  4. 内联语言检测脚本:var supportedLocalePrefixes = ['zh', 'ja', 'es', 'pt'];
  5. locales 增加 es / pt 条目(label、lang、link、themeConfig.nav)
  6. PAGE_SEO 可按需补充 es / pt 的页级 SEO(可后补)

10.4 页面骨架

ja/ 的文件清单为模板,将英文根目录同名 .md 复制到新语言目录:

bash
# 伪代码:对 ja/ 下每个相对路径 rel,
# 若根目录存在 rel 则复制到 es/rel(英文内容),否则复制 ja/rel 占位
for rel in $(find ja -name '*.md' | sed 's#^ja/##'); do
  src=""; [ -f "$rel" ] && src="$rel" || src="ja/$rel"
  for lang in es pt; do mkdir -p "$(dirname "$lang/$rel")"; cp "$src" "$lang/$rel"; done
done

⚠️ 首页 index.md 必须重定向到对应语言首页(参考 es/index.md 使用 window.location.replace('/es/home')),不能沿用英文 meta refresh(否则跳回 /home)。

10.5 全局 CSS

css
.es { display: none !important; }
.pt { display: none !important; }
.lang-es .es { display: revert !important; }
.lang-es .en { display: none !important; }
.lang-pt .pt { display: revert !important; }
.lang-pt .en { display: none !important; }

⚠️ 记得在 .lang-zh / .lang-ja 规则中补上 .es / .pt 的隐藏,避免跨语言串显。


11. 新增语言检查清单(Quick Start)

以下为每次新增语言的最终核对清单:

基础设施

  • [ ] i18n.tslocaleOf 识别新语言
  • [ ] i18n.tslocalePath 前缀
  • [ ] i18n.ts:新增 isXxx computed(如需)
  • [ ] i18n.tst() 英文回退(未翻译时不显示占位符)
  • [ ] custom.css:全局 .lang-xx 规则 + 其他语言隐藏新语言

配置

  • [ ] config.mtsSITE_META[xx]
  • [ ] config.mtsLOCALES
  • [ ] config.mtslocaleOfPage / stripLocaleOfPage
  • [ ] config.mtssupportedLocalePrefixes(语言检测脚本)
  • [ ] config.mtslocales 条目(label/lang/link/nav)

页面

  • [ ] 新语言目录(xx/)已创建,90+ 页面就绪
  • [ ] xx/index.md 重定向到 /xx/home
  • [ ] 页面内容已翻译(首版可英文骨架)

验证

  • [ ] npm run docs:build 无编译错误
  • [ ] /es//pt/ 首页可访问
  • [ ] 顶部语言切换器显示 Español / Português
  • [ ] 导航链接、侧边栏、登录页正常
  • [ ] 切换语言后回退显示英文(未翻译部分)

后续增量(可选,完善翻译)

  • [ ] messages 中添加 es / pt 完整翻译区块
  • [ ] 组件模式 B(.en/.zh/.ja span)为每个 span 增加 .es / .pt
  • [ ] 组件模式 C(v-if isChinese/isJapanese)增加 isSpanish / isPortuguese 分支
  • [ ] L() 辅助函数增加 es/pt 参数与数据字段
  • [ ] PAGE_SEO 补全新语言页级 SEO