---
title: 国際化 (i18n)
description: ICU MessageFormat 2 メッセージ、複数ロケール辞書、静的チェッカー、ランタイムモジュール、エディタ支援。
---

# 国際化 (i18n)

Ox Content は **ICU MessageFormat 2（MF2）** を中心にした i18n ツールキット一式を載せます。

- JSON / YAML から入れ子キーで読む、複数ロケールの **辞書**。
- 手書きの **MF2 パーサ**（単純メッセージ、`.input` / `.local` 宣言、`.match` 分岐）。
- ビルド時の **静的チェッカー**（欠けているキー、使われていないキー、ロケール間の変数不一致、MF2 構文エラー）。
- `t()` と `Intl` バックのフォーマッタを持つ **ランタイム仮想モジュール**。
- **CLI**（`vpx oxct i18n`）と、エディタ連携用の **LSP**。

このドキュメントサイトはファイルツリーのロケール配置です。英語ページは `/…`、日本語ページは `/ja/…` です。ヘッダーのロケールスイッチャーは、兄弟ページがあればそこへ飛びます。サイドバーとヘッダーのリンクは、兄弟があれば現在ロケールに留まります。手書きの日本語ガイドは英語と同じ深さです。生成 API ページは英語のままです。

## 有効化

```ts
// vite.config.ts
import { oxContent } from "@ox-content/vite-plugin";

export default {
  plugins: [
    oxContent({
      i18n: {
        enabled: true,
        dir: "content/i18n",
        defaultLocale: "en",
        locales: [
          { code: "en", name: "English" },
          { code: "ja", name: "日本語" },
          { code: "ar", name: "العربية", dir: "rtl" },
        ],
      },
    }),
  ],
};
```

### オプション

| オプション          | 既定             | 説明                                                                                                            |
| ------------------- | ---------------- | --------------------------------------------------------------------------------------------------------------- |
| `enabled`           | `false`          | i18n を有効にする。                                                                                             |
| `dir`               | `'content/i18n'` | プロジェクトルートからの相対辞書ディレクトリ。                                                                  |
| `defaultLocale`     | `'en'`           | 既定ロケールタグ（BCP 47）。                                                                                    |
| `locales`           | —                | 使えるロケール: `{ code, name, dir? }`（`dir` は `'ltr'` / `'rtl'`）。                                          |
| `hideDefaultLocale` | `true`           | true なら `/page` が既定ロケール、`/ja/page` はプレフィックス付き。false ならすべてのロケールにプレフィックス。 |
| `check`             | `true`           | ビルド中に静的チェッカーを走らせる。                                                                            |
| `functionNames`     | `['t', '$t']`    | ソースから使われたキーを探すときに検出する翻訳関数名。                                                          |

## 辞書

各ロケールは `dir` 以下の JSON または YAML ファイルです。入れ子キーはドットで平坦化されるので、辞書と呼び出し側は同じキー空間を共有します。

```yaml
# content/i18n/en.yaml
nav:
  home: "Home"
  docs: "Documentation"
cart:
  items: "{$count :number} items in your cart"
```

```jsonc
// content/i18n/ja.json
{
  "nav": { "home": "ホーム", "docs": "ドキュメント" },
  "cart": { "items": "カートに {$count :number} 件" },
}
```

既定ロケール以外で欠けているキーは、実行時に既定ロケールへ落ちます。

## MessageFormat 2 メッセージ

値は MF2 メッセージです。プレーンテキスト以外では次が使えます。

```text
# 書式関数付きの補間
{$count :number} items

# 宣言 + マッチ（複数形 / 選択）
.input {$count :number}
.match $count
  one  {{You have {$count} item.}}
  *    {{You have {$count} items.}}
```

CLI からメッセージを検証します。

```bash
vpx oxct i18n validate "{$count :number} items"
vpx oxct i18n validate ".match {$n}\n one {{1}}\n * {{many}}" --ast
```

## 静的チェック

`check: true` のとき、ビルドはソースから使われたキーを拾い、辞書と突き合わせて 4 種類の問題を報告します。

- **欠けているキー** — コードで使われているが、あるロケールにない。
- **使われていないキー** — 辞書にあるが、一度も参照されていない。
- **型の不一致** — 同じキーでプレースホルダ / 変数集合がロケール間で違う。
- **構文エラー** — 辞書値の不正な MF2。

`@ox-content/vite-plugin` がインストールする `oxct` バイナリとして単体でも走れます（CI でも便利です。エラーがある場合のみ非ゼロで終了し、警告だけの場合は正常終了します）。

```bash
vpx oxct i18n check --dict-dir content/i18n --src src
vpx oxct i18n check --dict-dir content/i18n --src src --format json
vpx oxct i18n check --dict-dir content/i18n --src src --default-locale en
```

キーは OXC パーサ経由で TS / JS の呼び出し（`t(...)`、`$t(...)`、`this.t(...)`、`i18n.t(...)`）と、Markdown（`{{t(...)}}`）から集めます。検出する関数名は `functionNames` で変えられます。

## ランタイムモジュール

仮想モジュールを import すると、読み込んだ辞書とプラットフォームの `Intl` API を後ろに持つ翻訳・書式ヘルパーが得られます。

```ts
import {
  t,
  localePath,
  getLocaleFromPath,
  formatDate,
  formatNumber,
  formatRelativeTime,
  formatList,
  formatDisplayName,
  i18nConfig,
} from "virtual:ox-content/i18n";

t("cart.items", { count: 3 }); // "3 items in your cart"
t("nav.home", {}, "ja"); // ロケールを強制 → "ホーム"

localePath("/docs", "ja"); // "/ja/docs"
getLocaleFromPath("/ja/docs"); // "ja"

formatNumber(1234.5, "ja"); // "1,234.5"
formatRelativeTime(-2, "day", "en"); // "2 days ago"
```

`Intl` フォーマッタはロケールごとにキャッシュされます。ロケールメタデータは任意の文字方向も持つので、RTL ロケールは正しく描画されます。

## エディタ支援

同梱の言語サーバ（`vpx oxct lsp`）は、辞書キーの補完、各ロケールの翻訳ホバー、辞書ファイルへの定義ジャンプ、既定ロケール値を出すインレイヒント、チェッカーと同じ欠けている / 使われていないキー診断を提供します。stdio で動きます。

```bash
vpx oxct lsp
```

VS Code、Zed、Neovim と連携します。配線はプロジェクト README のエディタ支援節を見てください。
