グローバルなユーザーに向けてReactアプリケーションを構築するには、堅牢な国際化(i18n)戦略が必要です。react-i18nextは、実績のあるi18nextフレームワークを基盤とした、最も人気のあるReactローカライゼーションライブラリです。本ガイドでは、初期セットアップからAIを活用した翻訳による本番環境向けの自動化まで、Reactアプリをローカライズするために必要なすべてを順を追って解説します。
react-i18nextはReact国際化のデファクトスタンダードであり、世界中の何千もの本番アプリケーションで信頼されています。開発者がこれを選ぶ理由は以下の通りです:
react-i18nextとコアとなるi18nextライブラリをインストールします:
npm install react-i18next i18nextこれらの人気プラグインは、自動言語検出や翻訳の遅延読み込み機能を追加してi18nextのセットアップを強化します:
# Language detector (auto-detects user language)
npm install i18next-browser-languagedetector
# HTTP backend (load translations from server)
npm install i18next-http-backend適切に整理されたプロジェクト構造は、言語を追加しても翻訳の保守性を維持するのに役立ちます:
src/
├── i18n/
│ └── i18n.ts ← i18next configuration
├── locales/
│ ├── en/
│ │ └── translation.json ← English (source)
│ ├── fr/
│ │ └── translation.json ← French
│ ├── de/
│ │ └── translation.json ← German
│ ├── ja/
│ │ └── translation.json ← Japanese
│ └── es/
│ └── translation.json ← Spanish
├── components/
├── App.tsx
└── index.tsxreact-i18nextは翻訳にネストされたJSONファイルを使用します。キーはドット記法、{{variables}}による補間、組み込みの複数形をサポートしています:
// locales/en/translation.json
{
"welcome": {
"title": "Welcome to our platform",
"greeting": "Hello, {{name}}!",
"description": "Explore features and get started."
},
"nav": {
"home": "Home",
"dashboard": "Dashboard",
"settings": "Settings",
"logout": "Log out"
},
"cart": {
"empty": "Your cart is empty",
"item_one": "{{count}} item in your cart",
"item_other": "{{count}} items in your cart",
"checkout": "Proceed to checkout"
}
}i18nextは、翻訳を読み込むための2つの主要なアプローチ(HTTPバックエンドによる遅延読み込みと、バンドルされたリソース)をサポートしています。アプリのニーズに合わせて選択してください。
サーバー上のJSONファイルから必要に応じて翻訳を読み込みます。これにより初期バンドルサイズを小さく保つことができ、多くの言語や大きな翻訳ファイルを持つアプリに最適です:
// src/i18n/i18n.ts
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import HttpBackend from "i18next-http-backend";
i18n
.use(HttpBackend)
.use(LanguageDetector)
.use(initReactI18next)
.init({
fallbackLng: "en",
supportedLngs: ["en", "fr", "de", "ja", "es"],
defaultNS: "translation",
interpolation: {
escapeValue: false, // React already escapes by default
},
backend: {
loadPath: "/locales/{{lng}}/{{ns}}.json",
},
detection: {
order: ["localStorage", "navigator", "htmlTag"],
caches: ["localStorage"],
},
});
export default i18n;翻訳を直接バンドルにインポートします。小規模なアプリや、ネットワークリクエストなしで即座に翻訳を利用する必要がある場合に最適です:
// src/i18n/i18n.ts — Bundled approach (no HTTP backend)
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import en from "../locales/en/translation.json";
import fr from "../locales/fr/translation.json";
import de from "../locales/de/translation.json";
i18n
.use(LanguageDetector)
.use(initReactI18next)
.init({
fallbackLng: "en",
supportedLngs: ["en", "fr", "de"],
defaultNS: "translation",
interpolation: {
escapeValue: false,
},
resources: {
en: { translation: en },
fr: { translation: fr },
de: { translation: de },
},
});
export default i18n;コンポーネントをレンダリングする前に、アプリのエントリーポイントでi18n設定ファイルをインポートします。これにより、UIがレンダリングされる前に翻訳が読み込まれることが保証されます:
// src/index.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./i18n/i18n"; // Initialize i18next before rendering
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);react-i18nextは、コンポーネントを翻訳するための2つの主要なAPIを提供しています。プログラムによるアクセスのためのuseTranslationフックと、JSXを含むリッチテキストのためのTransコンポーネントです。
useTranslationフックは、関数コンポーネントで翻訳にアクセスするための最も一般的な方法です。t()関数を提供し、言語が変更されると自動的に再レンダリングされます:
import { useTranslation } from "react-i18next";
function WelcomeBanner() {
const { t } = useTranslation();
return (
<div>
<h1>{t("welcome.title")}</h1>
<p>{t("welcome.greeting", { name: "Alice" })}</p>
<p>{t("welcome.description")}</p>
</div>
);
}翻訳にHTMLやJSX要素(太字、リンクなど)が含まれる場合は、Transコンポーネントを使用します。翻訳内でReactコンポーネントツリーを保持できます:
import { Trans } from "react-i18next";
function RichTextExample() {
return (
<p>
<Trans i18nKey="richText.welcome">
Welcome to <strong>our platform</strong>.
Visit your <a href="/dashboard">dashboard</a> to get started.
</Trans>
</p>
);
}
// In the translation file:
// "richText.welcome": "Welcome to <1>our platform</1>. Visit your <3>dashboard</3> to get started."i18nextは、各言語のICU複数形ルールに基づいて複数形を自動的に処理します。countパラメータを渡すと、i18nextが正しい複数形を選択します:
// In translation JSON:
// "cart.item_one": "{{count}} item in your cart"
// "cart.item_other": "{{count}} items in your cart"
import { useTranslation } from "react-i18next";
function CartSummary({ itemCount }: { itemCount: number }) {
const { t } = useTranslation();
return (
<p>{t("cart.item", { count: itemCount })}</p>
);
}
// itemCount=0 → "0 items in your cart"
// itemCount=1 → "1 item in your cart"
// itemCount=5 → "5 items in your cart"名前空間を使用すると、機能やドメインごとに翻訳を別々のファイルに分割できます。これにより保守性が向上し、翻訳バンドルの遅延読み込みが可能になります:
// src/i18n/i18n.ts
i18n.init({
defaultNS: "common",
ns: ["common", "dashboard", "auth", "errors"],
backend: {
loadPath: "/locales/{{lng}}/{{ns}}.json",
},
});
// Usage in components:
import { useTranslation } from "react-i18next";
function DashboardPage() {
// Load specific namespace
const { t } = useTranslation("dashboard");
return <h1>{t("title")}</h1>;
}
function LoginForm() {
// Load multiple namespaces
const { t } = useTranslation(["auth", "common"]);
return (
<form>
<h2>{t("auth:login.title")}</h2>
<button>{t("common:submit")}</button>
</form>
);
}react-i18nextを使えば、言語の切り替えはシームレスです。i18n.changeLanguage()を呼び出すだけで、useTranslationを使用しているすべてのコンポーネントが新しい言語で自動的に再レンダリングされます:
import { useTranslation } from "react-i18next";
const LANGUAGES = [
{ code: "en", label: "English" },
{ code: "fr", label: "Français" },
{ code: "de", label: "Deutsch" },
{ code: "ja", label: "日本語" },
{ code: "es", label: "Español" },
];
function LanguageSwitcher() {
const { i18n } = useTranslation();
const changeLanguage = (lng: string) => {
i18n.changeLanguage(lng);
};
return (
<select
value={i18n.language}
onChange={(e) => changeLanguage(e.target.value)}
>
{LANGUAGES.map(({ code, label }) => (
<option key={code} value={code}>
{label}
</option>
))}
</select>
);
}react-i18nextはReact Suspenseと統合されており、非同期の翻訳読み込みを適切に処理します。HTTPバックエンドを使用する場合、翻訳の取得中にSuspenseがクリーンな読み込み状態を提供します:
import { Suspense } from "react";
import { useTranslation } from "react-i18next";
// i18next supports React Suspense for async translation loading
function App() {
return (
<Suspense fallback={<div>Loading translations...</div>}>
<MainContent />
</Suspense>
);
}
function MainContent() {
const { t, ready } = useTranslation();
// With Suspense, 'ready' is always true here
return <h1>{t("welcome.title")}</h1>;
}i18nextは完全なTypeScript統合をサポートしています。i18nextモジュールを拡張することで、すべての翻訳キーに対してオートコンプリートとコンパイル時のチェックが可能になり、タイプミスや翻訳の欠落を防ぐことができます:
// src/i18n/types.ts
import "i18next";
import translation from "../locales/en/translation.json";
declare module "i18next" {
interface CustomTypeOptions {
defaultNS: "translation";
resources: {
translation: typeof translation;
};
}
}
// Now t() calls are fully type-safe:
// t("welcome.title") ✅ Autocomplete works
// t("welcome.greeting") ✅ Valid key
// t("invalid.key") ❌ TypeScript errorApp Routerを使用するNext.jsアプリケーションでは、サーバーコンポーネントとクライアントコンポーネントの両方でi18nextを使用できます。リクエスト間で状態が共有されないように、サーバーサイド翻訳用に個別のi18nextインスタンスを作成してください:
// next-i18next.config.js (Next.js App Router)
// For Next.js 13+ with App Router, use next-intl or i18next directly
// src/i18n/server.ts
import { createInstance } from "i18next";
import { initReactI18next } from "react-i18next/initReactI18next";
export async function getServerTranslation(lng: string) {
const i18nInstance = createInstance();
await i18nInstance.use(initReactI18next).init({
lng,
fallbackLng: "en",
resources: {
[lng]: {
translation: (await import(`../locales/${lng}/translation.json`)).default,
},
},
});
return i18nInstance;
}
// In a Server Component:
export default async function Page({ params }: { params: { lng: string } }) {
const i18n = await getServerTranslation(params.lng);
const t = i18n.t.bind(i18n);
return <h1>{t("welcome.title")}</h1>;
}react-i18nextのセットアップは半分に過ぎません。すべてのターゲット言語に対して高品質な翻訳が必要です。数十個のJSONファイルを手動で翻訳するのは時間がかかり、コストが高く、ミスも発生しやすくなります。AIを活用した翻訳がその状況を一変させます。
l10n.devは開発者のローカライゼーションワークフローのために特別に構築されました。JSON翻訳ファイルをネイティブに理解し、機械的ではない自然な翻訳を生成します:
ai-l10n npmパッケージは、AI翻訳を開発ワークフローに直接統合します。コマンドラインからJSONファイルを翻訳しましょう:
# Install the l10n.dev CLI
npm install ai-l10n
# Translate your JSON files to multiple languages at once
npx ai-l10n translate src/locales/en/translation.json \
--languages fr,de,ja,es,ko,zh-CN翻訳が常に最新の状態になるよう、ビルドパイプラインに翻訳の自動化を追加します:
{
"scripts": {
"translate": "ai-l10n translate src/locales/en/translation.json --languages fr,de,ja,es,ko --update",
"pretranslate": "npm run translate",
"dev": "vite",
"build": "npm run translate && vite build"
}
}LANGUAGES = fr,de,ja,es,ko,zh-CN
translate:
npx ai-l10n translate src/locales/en/translation.json --languages $(LANGUAGES) --update
dev: translate
npx vite
build: translate
npx vite buildCI/CD統合と自動化の詳細については、以下を参照してください:ローカライゼーション自動化ガイド
React i18nextのJSONファイルをVS Codeから直接翻訳できます。l10n.dev拡張機能を使えば、エディタを離れることなくファイルを翻訳可能です:
これで、react-i18nextを使用して完全にローカライズされたReactアプリケーションを構築するために必要なすべてが揃いました。i18nextの成熟したエコシステムの力とAIを活用した翻訳を組み合わせて、あらゆる言語のアプリを迅速にリリースしましょう。
react-i18nextは、Reactアプリケーション向けに、本番環境ですぐに使える完全なローカライゼーションソリューションを提供します。フックベースのAPI、名前空間サポート、TypeScript統合、SSR互換性により、アプリが必要とするあらゆるi18n要件に対応します。
react-i18nextとl10n.devのAI翻訳を組み合わせて、翻訳のボトルネックを解消しましょう。数秒でJSONファイルを翻訳し、CI/CDパイプラインと統合して、自信を持ってグローバルにリリースしてください。
私たちの使命は、ソフトウェアのローカライゼーションを迅速かつ手頃な価格で、開発者に優しいものにすることです。今すぐl10n.devを試して、AIがどのようにReactのローカライゼーションワークフローを変革できるかをご確認ください。