# 国際化

## 国際化ファイル

プラグインでは、フロントエンドとバックエンド両方の多言語ファイルが`src/locale`フォルダーに保存されます。

```bash
|- /plugin-i18n
  |- /src
    |- /locale      # 多言語フォルダー
      |- en-US.ts   # 英語ファイル
      |- zh-CN.ts   # 中国語ファイル
```

対応する多言語ファイル（`/src/locale/${lang}.ts`）に翻訳エントリを追加するだけでOKです。初めて多言語ファイルを追加する場合は、変更を反映させるためにアプリケーションの再起動が必要です。翻訳エントリが正常に追加されたかを確認するには、`app:getLang` APIをチェックしてください。

デフォルトURL: http://localhost:13000/api/app:getLang?locale=zh-CN

## i18n関連API

- サーバー
  - app.i18n
  - app.t(text, options)
  - ctx.i18n
  - ctx.t(text, options)
  - plugin.t()
- クライアント
  - ctx.i18n
  - ctx.t(text, options)
  - plugin.t()
  - useT()
- ユーティリティ
  - tExpr(text, options)
- React-i18next
  - useTranslation(ns)
  - withTranslation(ns)

## サーバー

### app.i18n <Badge>server</Badge>

`app.i18n`はグローバルなi18nインスタンスで、通常はCLIで使用されます。例えば、`inquirer`と組み合わせてコマンドラインのインタラクションを実装する際に利用できます。

```ts
import select from '@inquirer/select';
import input from '@inquirer/input';

export class PluginSampleI18nServer extends Plugin {
  load() {
    this.app.command('test-i18n').action(async () => {
      const answer1 = await select({
        message: '言語を選択してください',
        choices: [
          {
            name: '中国語',
            value: 'zh-CN',
          },
          {
            name: '英語',
            value: 'en-US',
          },
        ],
      });
      await this.app.changeLanguage(answer1);
      const answer2 = await input({
        message: app.i18n.t('名前を入力してください'),
      });
      console.log(app.i18n.t(`あなたの名前は{{name}}です`, { name: answer2 }));
    });
  }
}
```

### app.t(text, options) <Badge>server</Badge>

### ctx.i18n <Badge>server</Badge>

`ctx.i18n`はグローバルな`app.i18n`の`cloneInstance`です。各リクエストの`ctx`は完全に独立しており、クライアントの言語に基づいて多言語情報を提供します。

クライアントからのリクエストパラメータは、クエリ文字列に含めることができます。

```bash
GET /?locale=en-US HTTP/1.1
Host: localhost:13000
```

または、リクエストヘッダーに含めることもできます（推奨）。

```bash
GET / HTTP/1.1
Host: localhost:13000
X-Locale: en-US
```

例

```ts
export class PluginSampleI18nServer extends Plugin {
  load() {
    this.app.use(async (ctx, next) => {
      if (ctx.path === '/api/test-i18n') {
        ctx.body = `${ctx.i18n.t('こんにちは')} ${ctx.i18n.t('世界')}`;
      }
      await next();
    });
  }
}
```

こちらで確認できます: http://localhost:13000/api/test-i18n?locale=zh-CN

### ctx.t(text, options) <Badge>server</Badge>

### plugin.t() <Badge>server</Badge>

## クライアント

### ctx.i18n <Badge>client</Badge>

### ctx.t(text, options) <Badge>client</Badge>

### plugin.t()

### useT()

## ユーティリティ関数

### tExpr(text) <Badge>server</Badge> <Badge>client</Badge>

## React-i18next

### useTranslation(ns) <Badge>client</Badge>

### withTranslation(ns) <Badge>client</Badge>