---
title: "国际化"
description: "用 @nuxtjs/i18n 为文档站开启多语言：安装与配置、内容目录约定、按语言生成的内容集合、界面文案覆盖与 hreflang SEO。未配置时站点按单语言运行，也可只切换界面语言。"
canonical_url: "https://docs.mhaibaraai.cn/docs/guide/i18n"
---
# 国际化

> 用 @nuxtjs/i18n 为文档站开启多语言：安装与配置、内容目录约定、按语言生成的内容集合、界面文案覆盖与 hreflang SEO。未配置时站点按单语言运行，也可只切换界面语言。

## 两种模式

国际化是按需启用的：

- **单语言**（默认）：不安装 `@nuxtjs/i18n`，URL 不带语言前缀，界面文案取自内置翻译，语言由 `app.config` 的 `i18n.locale` 决定。
- **多语言**：在 `nuxt.config.ts` 的 `modules` 中加入 `@nuxtjs/i18n` 并配置 `i18n.locales` 后，Layer 自动启用本地化路由、按语言划分的内容集合、语言切换器与 hreflang。

两种模式下，组件与页面都通过 [`useMovkI18n()`](https://docs.mhaibaraai.cn/docs/reference/composables/use-movk-i18n) 读取当前语言、翻译与本地化路径，调用方无需判断是否启用了 i18n。

## 单语言站点

只需切换界面语言时，在 `app.config.ts` 中设置 `i18n.locale`：

```ts [app/app.config.ts]
export default defineAppConfig({
  i18n: {
    locale: 'en'
  }
})
```

默认值为 `zh-CN`。内置翻译目前提供 `zh-CN` 与 `en` 两种，它决定目录标题、编辑链接、搜索、AI 助手等界面文案。

## 多语言站点

### 安装 `@nuxtjs/i18n`

`@nuxtjs/i18n` 是 Layer 的可选 peer 依赖，需要在项目中安装：

```bash [pnpm]
pnpm add @nuxtjs/i18n
```

```bash [npm]
npm install @nuxtjs/i18n
```

```bash [yarn]
yarn add @nuxtjs/i18n
```

```bash [bun]
bun add @nuxtjs/i18n
```

### 配置 `nuxt.config.ts`

在 `modules` 中加入 `@nuxtjs/i18n`，声明默认语言与语言列表：

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  extends: ['@movk/nuxt-docs'],

  modules: ['@nuxtjs/i18n'],

  i18n: {
    defaultLocale: 'zh-CN',
    locales: [
      { code: 'zh-CN', name: '简体中文' },
      { code: 'en', name: 'English' }
    ]
  }
})
```

`locales` 中只写 `code` 与 `name`，不要声明 `file`：Layer 会合并内置翻译与站点 `i18n/locales/` 下的同名文件后统一注册（见 [站点翻译](#%E7%AB%99%E7%82%B9%E7%BF%BB%E8%AF%91)）；声明 `file` 时 `@nuxtjs/i18n` 会自行加载该文件，文件不存在则构建失败。

路由策略由 Layer 固定为 `prefix_except_default`，无需设置 `strategy`：默认语言无前缀（`/docs`），其他语言带前缀（`/en/docs`）。

### 组织内容目录

默认语言的内容保持在 `content/` 根目录，其他语言放在 `content/{code}/` 下，目录结构一一对应：

```text
content/
├── index.md              # 默认语言首页 → /
├── docs/                 # 默认语言文档 → /docs/*
│   └── 1.getting-started/
│       └── 1.index.md
├── releases.yml          # 默认语言版本发布页（可选）
└── en/
    ├── index.md          # 英文首页 → /en
    ├── docs/             # 英文文档 → /en/docs/*
    │   └── 1.getting-started/
    │       └── 1.index.md
    └── releases.yml      # 英文版本发布页（可选）
```

## 内容集合

Layer 为每种语言生成一组 Nuxt Content 集合。默认语言使用基础名，其他语言加上语言代码后缀（`-` 替换为 `_`）：

| 内容 | 默认语言 | 其他语言（以 `en`、`zh-TW` 为例） | 来源 |
| --- | --- | --- | --- |
| 文档 | `docs` | `docs_en`、`docs_zh_TW` | `content/docs/**`、`content/{code}/docs/**` |
| 首页 | `landing` | `landing_en` | `content/index.md`、`content/{code}/index.md` |
| 版本发布 | `releases` | `releases_en` | `content/releases.{md,yml}` |
| 案例 | `templates` | `templates_en` | `content/templates.{md,yml}` |

某种语言缺少 `releases` 或 `templates` 文件时，该语言下对应路由返回 404，其他语言不受影响。自定义页面查询内容时，用 `useMovkI18n()` 返回的 `docsCollection`、`landingCollection` 等取得当前语言的集合名。

## 语言的有效条件

构建时 Layer 会检查 `i18n.locales` 中的每一种语言，同时满足以下两项才会生效，否则跳过并在终端输出告警：

1. 该语言有翻译文件：Layer 内置了 `zh-CN` 与 `en`，其他语言由站点提供 `i18n/locales/{code}.json`；
2. 存在内容目录 `content/{code}/`。默认语言的内容在 `content/` 根目录，不做此项检查。

```text [terminal]
[movk-docs] 缺少内容目录 content/ja/，已跳过 locale "ja"
```

### 站点翻译

在站点根目录的 `i18n/locales/` 中放置 `{code}.json`，构建时会与 Layer 内置翻译合并，站点中的值优先：

- **新增语言**：如 `i18n/locales/ja.json`，只需翻译需要的键，缺失的键回退到英文内置文案；
- **覆盖内置文案**：如 `i18n/locales/en.json` 中只写 `{ "docs": { "tocTitle": "Contents" } }`，其余键保持内置值。

```json [i18n/locales/ja.json]
{
  "docs": {
    "tocTitle": "目次",
    "copyPage": "ページをコピー"
  }
}
```

可用的键见 Layer 的 [内置翻译文件](https://github.com/mhaibaraai/movk-nuxt-docs/blob/main/layer/i18n/locales/en.json)。修改站点翻译后需重启开发服务器。

## 界面文案

界面文案按 **app.config 中的值 ?? 当前语言的内置翻译** 解析。`app.config` 中的文案字段（如 `toc.title`、`aside.filter.placeholder`、`aiChat.texts.*`）默认为空，由翻译提供；设置后在所有语言中都使用该值。

需要按语言区分的导航文案，在 `header.nav` 与 `docs.categories` 中写成以语言代码为键的对象，详见[导航与分类](https://docs.mhaibaraai.cn/docs/guide/navigation)：

```ts [app/app.config.ts]
export default defineAppConfig({
  header: {
    nav: [
      { label: { 'zh-CN': '文档', 'en': 'Docs' }, to: '/docs/getting-started' }
    ]
  }
})
```

站内链接会自动加上当前语言前缀，`/docs/getting-started` 在英文下指向 `/en/docs/getting-started`。

在自己的组件中，启用 i18n 后 Layer 打开了 `@nuxtjs/i18n` 的 typed messages，`useI18n().t` 能补全内置与自定义的全部 key；`useMovkI18n().t` 在两种模式下都可用，但 key 没有类型提示。

## 语言切换器

启用 i18n 且有两种以上有效语言时，页头右侧出现语言切换器（`LanguageSwitcher`），列出全部有效语言，切换后跳到当前页面在目标语言中的对应路径。它在[覆盖契约](https://docs.mhaibaraai.cn/docs/guide/customization)内，可以用同名组件替换。

## 多语言 SEO

存在两种以上有效语言时，`useLocaleSeo()` 在每个页面注入：

- 每种语言的 `<link rel="alternate" hreflang="…">`，以及指向第一种语言的 `x-default`；
- 当前语言的 `og:locale`（如 `zh_CN`）。

`<html lang>` 与 `dir` 由 `@nuxt/ui` 的 locale 按当前语言设置。站点地图由 `@nuxtjs/sitemap` 按语言拆分，入口为 `/sitemap_index.xml`。

首次访问时的浏览器语言重定向由 `@nuxtjs/i18n` 的 `detectBrowserLanguage` 控制，需要固定首页语言时在 `i18n` 配置中关闭：

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  i18n: {
    detectBrowserLanguage: false
  }
})
```

## i18n 模板

需要直接开始一个中英双语站点时，使用 i18n 模板，它预置了 `zh-CN`（默认）与 `en` 两种语言、对应的内容目录和配置：

```bash [terminal]
npx nuxi init -t gh:mhaibaraai/movk-nuxt-docs/templates/i18n my-docs
```


## Sitemap

See the full [sitemap](https://docs.mhaibaraai.cn/sitemap.md) for all pages.
