Skip to content

JS/TSアプリにi18nを追加する ​

このページは、ボタン、ラベル、メッセージがまだプレーンなソース言語のテキストであるJS/TSアプリ(React、Next.js、Node、またはCLI)向けです。extract は、t() または i18n.t() 内の文字列リテラルである場合にのみUI文字列を記録するため、現時点ではカタログは空になり、translate-ui には翻訳すべきものがありません。

手順:ツールをインストールし、i18nextをインストールし、extract を一度実行し、t が存在するように小さなセットアップファイルを追加し、ユーザー向けテキストをラップし、その後翻訳します。これがあなたのケースに当てはまるか不明ですか?最後に あなたのケースではない場合 を参照してください。

ツールをインストールし、キーを設定する ​

CLIをインストールし (インストール)、プロバイダーのAPIキーを設定します (プロバイダーとAPIキー)。Ollamaはキーを必要としません。

設定を初期化する ​

bash
ai-i18n-tools init -P openrouter

これにより ai-i18n-tools.config.json が書き込まれます。現時点では4つのキーが重要です。

  • sourceLocale: テキストが書かれている言語。どの言語でも有効です。このガイドでは英語が一般的な例です。
  • targetLocales: 追加する言語。
  • ui.sourceRoots: extract がスキャンするフォルダー。例えば src/。
  • ui.stringsJson と ui.flatOutputDir: カタログとロケールごとのファイルが書き込まれる場所。

その他のすべてのキーは 設定 にあります。

ランタイムライブラリをインストールする ​

ai-i18n-tools は i18next または react-i18next に依存しません。アプリがそれらをインストールします。

  • ランタイムで文字列を検索するすべてのJS/TSアプリ: i18next。
  • useTranslation() を呼び出すReactコンポーネント: react-i18next も。
bash
pnpm add i18next
# React components:
pnpm add react-i18next

extractを一度実行する ​

bash
ai-i18n-tools extract

次のステップのセットアップファイルは strings.json と ui-languages.json をインポートし、extract のみがそれらを書き込みます。t() の呼び出しが見つからない場合でも両方を書き込むため、アプリはコンパイルされます。0個の文字列を想定してください。ただし、package.json に description がある場合は1個です。これは、エクストラクターがデフォルトでそれを含めるためです (ui.uiExtractor.includePackageDescription)。

ブートストラップを追加する ​

i18nセットアップファイルを作成します。この最小限のバージョンで、文字列をラップして翻訳するのに十分です。SOURCE_LOCALE は ai-i18n-tools.config.json 内の sourceLocale と等しくなければなりません。

js
// src/i18n.js — adjust the import paths to match `ui` in your config
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import aiI18n from 'ai-i18n-tools/runtime';
import uiLanguages from './locales/ui-languages.json';
import stringsJson from './locales/strings.json';

export const SOURCE_LOCALE = 'en-GB';

void i18n.use(initReactI18next).init(aiI18n.defaultI18nInitOptions(SOURCE_LOCALE));
aiI18n.setupKeyAsDefaultT(i18n, { stringsJson });

i18n.on('languageChanged', aiI18n.applyDirection);
aiI18n.applyDirection(i18n.language);

const localeLoaders = aiI18n.makeLocaleLoadersFromManifest(
  uiLanguages,
  SOURCE_LOCALE,
  (code) => () => import(`./locales/${code}.json`),
);

export const loadLocale = aiI18n.makeLoadLocale(i18n, localeLoaders, SOURCE_LOCALE);
export default i18n;

Reactを使用していませんか?react-i18next のインポートと .use(initReactI18next) の呼び出しを削除してください。

アプリが複数形を使用し始めたら、複数形が解決されるようにソースロケールのフラットファイルを追加します。これにより、3番目のインポートと sourcePluralFlatBundle オプションが追加されます。これは i18nextを接続する に示されています。

最初のレンダリングの前に、アプリのエントリからこのファイルをインポートします。Next.jsでは、examples/nextjs-app/src/lib/i18n.ts と同じパターンで、クライアントモジュールからインポートします。

ハードコードされたコピーを置き換える ​

手動で行うか、コーディングエージェントにJS/TSプロンプトを貼り付けます。t()への引数は、ユーザーに表示されるべきソース言語の文です。フラットなロケールファイルは、その文をキーとしています。

JS/TSエージェントプロンプト

これをCursorまたは他のコーディングエージェントにコピーしてください。これはユーザー向けの文字列リテラルをラップします。それらを翻訳しません。

markdown
# Wrap user-facing JS/TS strings in t()

## Context

ai-i18n-tools extracts only string literals passed to `t()` or `i18n.t()`. The
literal is the source-language sentence and the catalog key (`t("Save")`, not
`t("saveButton")`). After this edit the app must behave the same when the active
locale is the source locale. Do not translate any string.

Bootstrap and call-shape reference:
https://wsj-br.github.io/ai-i18n-tools/guide/ui-strings/i18next-runtime
https://wsj-br.github.io/ai-i18n-tools/guide/ui-strings/t-calls-and-plurals

## Scope

Read `ui.sourceRoots` in `ai-i18n-tools.config.json` and edit only those trees
(JS/JSX/TS/TSX). Skip `className`, URLs and routes, import paths, ids, test ids,
enum and error codes, object keys used as identifiers, log field names, CSS,
regexes, comments, and text that is already inside `t()` or `i18n.t()`.

## Call shape

Install `i18next`. Install `react-i18next` when a component uses
`useTranslation()`. Run `ai-i18n-tools extract` once so `strings.json` and
`ui-languages.json` exist, then add the bootstrap from the Wire i18next guide.
`SOURCE_LOCALE` must equal config `sourceLocale`.

- React components: `const { t } = useTranslation()` and `{t("Save")}`.
- Module-level constants and non-React files: `i18n.t("…")`. Move a constant
  that would call `t()` at import time into a function or `useMemo(..., [t])`.
- Placeholders: `t("Hello {{name}}", { name })`. No template literal as a key.
- Plurals: `t("{{count}} items", { plurals: true, count })`.
- Next.js: import the bootstrap from a client module before render. Do not call
  `changeLanguage` on a shared i18next instance inside a server component. Use a
  per-request `createInstance()`, or a stateless flat-bundle lookup.

Before:

```jsx
<button>Save</button>
```

After:

```jsx
<button>{t("Save")}</button>
```

Before:

```js
console.log(`Hello ${name}`);
```

After:

```js
console.log(t("Hello {{name}}", { name }));
```

## Order

1. Install the libraries.
2. Run `ai-i18n-tools extract` once.
3. Add the bootstrap.
4. Wrap call sites.
5. Run `ai-i18n-tools extract` again. Do not run a translation yourself and do
   not hand-edit catalogs.

## Do not

- Do not translate, rename, or reword the source text.
- Do not introduce semantic keys (`saveButton`, `nav.home`).
- Do not hand-edit `strings.json`, flat locale JSON, or `ui-languages.json`.
- Do not change behaviour, layout, or test selectors.

## Verify

- `ai-i18n-tools extract` writes a non-empty catalog of the sentences you
  wrapped.
- The project's build, type check, and tests pass.
- With the source locale active, every wrapped string still shows the original
  sentence. Switch one target locale after `translate-ui` and confirm those
  sentences change.

## Report back

List files changed, each string you deliberately skipped with a one-line reason,
and any ambiguous case you left for a human (the same word used with different
meanings, concatenated sentences, or a plural you were not sure about).

JSX:

jsx
<button>Save</button>
<button>{t("Save")}</button>

Node、CLI、またはReact以外のモジュール:

js
console.log(`Hello ${name}`);
console.log(t("Hello {{name}}", { name }));

ルール (t()呼び出しと複数形にも記載):

  • キーはリテラルです。t(variable)と{'t(Hello ${name})'}は抽出されず、リテラルでない呼び出しは警告なしにスキップされます。
  • リテラル内のプレースホルダーは、i18next形式の{{name}}を使用し、2番目の引数で渡されます。
  • 複数形: 1つのソース文と{ plurals: true, count }。基数複数形を参照してください。_one / _otherキーを自分で作成しないでください。
  • ReactコンポーネントはuseTranslation()からtを取得します。他のファイルはi18n.tを呼び出します。インポート時に評価される定数は、関数またはuseMemo(..., [t])内に移動する必要があります。これにより、ロケールがロードされた後にt()が実行されます。
  • Next.jsサーバーコンポーネントは、共有i18nextインスタンスでchangeLanguageを呼び出してはなりません。同時リクエストはそのシングルトンを共有します。リクエストごとのcreateInstance()を使用するか、フラットバンドルのステートレスなルックアップを使用してください(Nextraハイブリッドを参照)。

これらはそのままにしてください: className、href、その他のURL、インポートパス、ID、テストID、エラーコード、識別子として使用されるオブジェクトキー、およびコメント内のテキスト。

抽出と翻訳 ​

リテラルが配置されたら:

bash
ai-i18n-tools extract
ai-i18n-tools translate-ui
ai-i18n-tools status

features.translateUIStringsがオンの場合、syncはextractとtranslate-uiを一緒に実行します。extractには、ラップした文がリストされているはずです。ui.flatOutputDirの下に生成されたロケールファイルを1つ開き、翻訳があることを確認してください。次に、extractがスキャンして書き込む内容については、UI文字列、ステップ2を参照してください。

examples/console-appは、src/main.jsがすでにラップされている小さなNodeアプリです。Next.jsの例はReactのブートストラップです。

言語切り替え ​

i18nextの配線で説明されているように、最初のレンダリングの前に保存されたロケールを復元します。その後、await loadLocale(code)に続いてawait i18n.changeLanguage(code)を呼び出すコントロールを追加します: 言語スイッチャーとRTL。

翻訳を維持する ​

ソーステキストを変更した後、syncを再実行します。キャッシュにより、新規または変更された文字列のみがモデルに送られます。推奨されるpackage.jsonスクリプトからスクリプトを追加し、CIでsyncを実行して翻訳がずれないようにします。

デフォルトのinitテンプレートはREADME.mdも翻訳します。READMEとMarkdownドキュメントにi18nを追加するを参照してください。

他のツールからの移行 ​

ai-i18n-toolsには独自の文字列抽出機能が含まれています。i18next-scanner、babel-plugin-i18next-extractなどを使用していた場合、移行後にそれらの開発依存関係を削除できます。既存のi18next名前空間JSONファイルは、JSONパイプラインに残すことができます。Intlayerの.content.ts辞書はmigrate-intlayerでインポートできます。Intlayerからの移行を参照してください。実行時にIntlayerを維持し、その翻訳のみを埋めるには、translate-intlayerを使用します。Intlayerをその場で翻訳するを参照してください。

当てはまりませんか? ​

現在のコード参照
すでにソース言語の文で t("…") または i18n.t("…") を使用している場合UI文字列 ステップ2~3、次に i18nextを組み込む
i18nextネームスペースJSON (t("saveButton") および en/translation.json)JSON。すべての呼び出しを変更する準備ができていない限り、これらのキーをソース言語の文に切り替えないでください
Intlayer辞書、Intlayerからの移行Intlayerからの移行
Intlayer辞書、Intlayerを維持する場合Intlayerをその場で翻訳する
単一のHTMLファイルプレーンHTML と mark-html
ドキュメントサイト、またはAstroページのHTMLウェブサイトまたはドキュメントサイトにi18nを追加する と Astroウェブサイト。t() は共有データとフロントマターのみに使用します
PythonアプリPythonアプリにi18nを追加する
リポジトリのREADMEまたはその他のMarkdownファイルREADMEとMarkdownドキュメントにi18nを追加する

MITライセンスの下で公開されています。