はじめに
この記事では、React / TypeScript 環境で react-i18next を使った多言語対応の実装方法を記載します。
react-i18next とは
react-i18next は、React アプリケーションに国際化(i18n)機能を提供するライブラリです。
i18next エコシステムをベースにしており、以下のような特徴があります。
- React Hooks に完全対応(useTranslation フックなど)
- TypeScript による型安全な翻訳キーの補完
- Trans コンポーネントによる複雑な翻訳の対応
- プラグインによる拡張性の高さ
- SSR(サーバーサイドレンダリング)への対応
i18next 本体は React に限定されず、Angular や Vue.js、さらには Node.js でも利用可能な汎用的な国際化フレームワークです。
react-i18next はその React バインディングとして、React の Context API や Hooks を活用した実装を提供しています。
開発環境
開発環境は以下の通りです。
- Windows 11
- React 19.2.0
- TypeScript 5.9.3
- Vite 7.2.4
- Node.js 24.11.1
- npm 11.6.4
- react-i18next 16.3.5
- i18next 25.7.1
- i18next-browser-languagedetector 8.2.0
インストール
まずは以下のコマンドでインストールします。
npm install react-i18next i18next --save
基本的な利用方法
i18n の初期化
src ディレクトリ配下に i18n.ts ファイルを作成し、i18next の設定を行います。
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
i18n.use(initReactI18next).init({
resources: {
ja: {
translation: {
welcome: "ようこそ",
greeting: "こんにちは、{{name}}さん",
},
},
en: {
translation: {
welcome: "Welcome",
greeting: "Hello, {{name}}",
},
},
},
fallbackLng: "en",
interpolation: {
escapeValue: false,
},
});
export default i18n;
アプリケーションへの適用
main.tsx で i18n をインポートします。
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./i18n";
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
useTranslation フックの利用
コンポーネント内で useTranslation フックを使って翻訳を行います。
import { FC } from "react";
import { useTranslation } from "react-i18next";
export const Welcome: FC = () => {
const { t } = useTranslation();
return (
<div>
<h1>{t("welcome")}</h1>
<p>{t("greeting", { name: "太郎" })}</p>
</div>
);
};
動作確認をします。
初期言語設定(lng)を日本語にしているので、「ようこそ」と「こんにちは、太郎さん」が表示されます。
言語切り替え
i18n.changeLanguage を利用することで、画面上からの言語切替が可能になります。
import { useTranslation } from "react-i18next";
function App() {
const { t, i18n } = useTranslation();
const changeLanguage = (lng: string) => {
i18n.changeLanguage(lng);
};
return (
<div>
<h1>{t("welcome")}</h1>
<p>{t("greeting", { name: "太郎" })}</p>
<div>
<button onClick={() => changeLanguage("ja")}>日本語</button>
<button onClick={() => changeLanguage("en")}>English</button>
</div>
</div>
);
}
export default App;
言語設定の自動検知
言語設定を自動検知したい場合、i18next-browser-languageDetector パッケージを利用します。
npm install --save i18next-browser-languagedetector
i18next-browser-languagedetector を使うように i18n.ts を更新します。
import i18n from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import { initReactI18next } from "react-i18next";
i18n
.use(LanguageDetector) // 追加
.use(initReactI18next)
.init({
resources: {
ja: {
translation: {
welcome: "ようこそ",
greeting: "こんにちは、{{name}}さん",
},
},
en: {
translation: {
welcome: "Welcome",
greeting: "Hello, {{name}}",
},
},
},
fallbackLng: "en",
interpolation: {
escapeValue: false,
},
});
export default i18n;
この設定により、以下の順序で言語が検知されます。
- クエリ文字列 (?lng=ja など)
- Cookie
- localStorage
- sessionStorage
- ブラウザの navigator
- HTML タグ
検知オプションのカスタマイズ
言語検知の動作をカスタマイズする場合は、detection オプションを指定します。
i18n
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources: {
// ...
},
fallbackLng: "en",
detection: {
order: ["navigator", "localStorage"],
caches: ["localStorage"],
},
interpolation: {
escapeValue: false,
},
});
-
order: 言語検知の優先順位を指定 -
caches: 検知した言語を保存する場所を指定
今回の設定では、クエリ文字列の値は反映されていません。
サポート言語の設定
アプリケーションでサポートする言語を明示的に指定することで、より適切な言語マッチングが可能になります。
翻訳ファイルの分離
翻訳データは、JSON ファイルに分離できます。
ディレクトリ構造
src/
├── locales/
│ ├── ja/
│ │ └── translation.json
│ └── en/
│ └── translation.json
├── i18n.ts
└── main.tsx
翻訳ファイルの作成
src/locales/ja/translation.json
{
"welcome": "ようこそ",
"greeting": "こんにちは、{{name}}さん",
"messages": {
"unread": "未読メッセージが{{count}}件あります"
}
}
src/locales/en/translation.json
{
"welcome": "Welcome",
"greeting": "Hello, {{name}}",
"messages": {
"unread": "You have {{count}} unread message(s)"
}
}
i18n 設定の更新
翻訳ファイルを resources で読み込みます。
import i18n from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import { initReactI18next } from "react-i18next";
import jaTranslation from "./locales/ja/translation.json";
import enTranslation from "./locales/en/translation.json";
i18n
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources: {
ja: { translation: jaTranslation },
en: { translation: enTranslation },
},
fallbackLng: "en",
interpolation: {
escapeValue: false,
},
});
export default i18n;
Trans コンポーネントの利用
HTML タグや React コンポーネントを含む翻訳には Trans コンポーネントを使用します。
翻訳ファイル
{
"richText": "これは<bold>太字</bold>のテキストです",
}
コンポーネント
import { Trans, useTranslation } from "react-i18next";
function App() {
const { t } = useTranslation();
return (
<div>
<h1>{t("welcome")}</h1>
<p>{t("greeting", { name: "太郎" })}</p>
<Trans i18nKey="richText" components={{ bold: <strong /> }} />
</div>
);
}
export default App;
TypeScript の型定義
TypeScript で翻訳キーの型安全性を確保するために、型定義を追加します。
i18next.d.ts
src ディレクトリ配下に i18next.d.ts ファイルを作成します。
import "i18next";
import jaTranslation from "./locales/ja/translation.json";
declare module "i18next" {
interface CustomTypeOptions {
defaultNS: "translation";
resources: {
translation: typeof jaTranslation;
};
}
}
これにより、t() 関数の引数に存在しないキーを指定した場合、TypeScript のコンパイルエラーが発生するようになります。
名前空間の利用
大規模なアプリケーションでは、翻訳を複数のファイルに分割して管理できます。
ディレクトリ構造
src/
├── locales/
│ ├── ja/
│ │ ├── common.json
│ │ └── home.json
│ └── en/
│ ├── common.json
│ └── home.json
i18n 設定
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import jaCommon from "./locales/ja/common.json";
import jaHome from "./locales/ja/home.json";
import enCommon from "./locales/en/common.json";
import enHome from "./locales/en/home.json";
i18n
.use(initReactI18next)
.init({
resources: {
ja: {
common: jaCommon,
home: jaHome,
},
en: {
common: enCommon,
home: enHome,
},
},
lng: "ja",
fallbackLng: "en",
defaultNS: "common",
interpolation: {
escapeValue: false,
},
});
export default i18n;
名前空間の指定
import { FC } from "react";
import { useTranslation } from "react-i18next";
export const Home: FC = () => {
const { t } = useTranslation("home");
return <h1>{t("title")}</h1>;
};
まとめ
react-i18next を使うことで、React / TypeScript アプリケーションに簡単に多言語対応を導入できます。
主なポイントは以下の通りです。
- useTranslation フックを使ったシンプルな翻訳の実装
- Trans コンポーネントによる HTML タグやコンポーネントを含む翻訳
- TypeScript による型安全な翻訳キーの管理
- 名前空間を使った大規模アプリケーションへの対応
i18next エコシステムには、さらに多くのプラグインや機能が用意されています。言語検出、翻訳の遅延読み込み、複数形の処理など、プロジェクトの要件に応じて柔軟にカスタマイズできます。






