開発

i18nextとは:翻訳ファイルの設計と複数形・補間・SSR読み込みの実装手順【v26対応】

i18nextとは:翻訳ファイルの設計と複数形・補間・SSR読み込みの実装手順【v26対応】

i18nextは、JavaScriptとTypeScriptのアプリに翻訳の仕組みを組み込むオープンソースの国際化ライブラリです。npm registryで2026年10月22日に確認した最新版は26.5.4(10月21日公開)で、ライセンスはMITでした。この記事では、i18nextが受け持つ範囲と導入手順、翻訳ファイルを名前空間で分ける設計、日本語でも気を抜けない複数形と補間の扱い、Next.jsのApp Routerでサーバー側から翻訳を読み込む構成、TypeScriptの型付けとv26での変更点、next-intlなど他ライブラリとの選び分けまでを、公式ドキュメントの記述をもとに実装の順番で整理します。

まとめ:i18nextを選ぶ条件と翻訳ファイル・SSR設計で先に決める3点

React、Vue、Node.jsのサーバー処理など、複数の実行環境で同じ翻訳ファイルを使い回したいなら、i18nextは第一候補です。翻訳の解決ロジックはコアに1つだけあり、各フレームワークとは連携用のパッケージでつなぐ構造なので、画面の技術が変わっても翻訳資産を作り直さずに済みます。

導入前に決めておくべき点は、名前空間の分け方、翻訳ファイルをバンドルに入れるか配信するか、サーバー側で翻訳を読み込むかの3つです。後から変えると、ファイルの置き場所と読み込みコードの両方を書き換えることになります。反対に、Next.jsのApp Routerだけで完結する新規サイトなら、App Router専用に作られたnext-intlのほうが設定は少なく済みます。

i18nextの定義|翻訳の解決を担うコアとフレームワーク連携の分担

最初に、i18nextが何を自動化し、どこからを連携パッケージに任せているのかを押さえます。

キーの解決・補間・複数形をコアが持ち描画を連携層に任せる構成

i18nextのコアは、翻訳キーから文言を引く処理、変数の埋め込み(補間)、件数に応じた複数形の切り替え、言語が見つからないときの代替言語への切り替えを受け持ちます。画面への描画は持っていません。Reactならreact-i18next、Next.jsならnext-i18nextといった連携パッケージが、言語を切り替えたときの再描画をつなぎます。

GitHubのリポジトリが掲げる標語は「learn once – translate everywhere」です。翻訳の取得方法も、JSONを直接渡す方法、HTTPで配信する方法、翻訳管理サービスから読む方法をプラグインで差し替えられます。国際化(i18n)とローカライズ(l10n)という用語の違いは、i18nとl10nの違いとAngularでの実装手順で整理しています。

26.5系の版と動作要件|TypeScript 5以上とIntl APIへの依存

npm registryの記録では、26系の最初の版である26.0.0は2026年3月28日の公開です。26.5.4のリリースが10月21日に出ており、マイナー版の更新が月単位で続いています。連携パッケージ側も追随していて、react-i18nextの17.1.0はpeerDependenciesでi18next 26.2.0以上を要求していました。

TypeScriptで型を付ける場合、公式のTypeScriptの説明ではv5以上が前提で、v4の環境はi18next 22.5.1に留める必要があると書かれています。もう1つの前提は、ブラウザやNode.jsが備えるIntl.PluralRulesです。複数形の判定をこのAPIに任せているため、React NativeのHermesのように未実装の環境ではpolyfillを足します。

i18nextの導入手順|initの設定からuseTranslationで表示するまで

ここからは手を動かす部分です。Reactのアプリを例に、インストールから画面表示までを通します。

npmで2パッケージを入れてi18n.tsに初期化処理を書く手順と設定値

コアと連携パッケージを入れ、初期化用のファイルを1つ作ります。翻訳文はまずresourcesに直接書き、動作を確かめてからファイルへ分ける順番が手戻りの少ない進め方です。

# コアとReact連携パッケージを入れる
npm install i18next react-i18next

// src/i18n.ts
import i18next from 'i18next';
import { initReactI18next } from 'react-i18next';

i18next.use(initReactI18next).init({
  lng: 'ja',
  fallbackLng: 'ja',        // 既定値は 'dev' なので必ず指定する
  supportedLngs: ['ja', 'en'],
  defaultNS: 'common',
  resources: {
    ja: { common: { greeting: 'こんにちは、{{name}}さん' } },
    en: { common: { greeting: 'Hello, {{name}}' } },
  },
});

// src/Greeting.tsx
import { useTranslation } from 'react-i18next';

export function Greeting() {
  const { t } = useTranslation();
  return <p>{t('greeting', { name: '山田' })}</p>;
}

src/i18n.tsはアプリの入口で1回だけ読み込みます。useTranslationの説明によると、引数を省いた場合はdefaultNSの名前空間が使われ、言語の切り替えはi18n.changeLanguage('en')で行います。

fallbackLngの既定値devと未設定のまま公開したときの失敗パターン

設定項目の一覧を見ると、fallbackLngの既定値は'dev'です。これを指定せずに公開すると、用意していない言語でアクセスされたときにdevという存在しない言語の翻訳を探しに行き、画面にキー名がそのまま表示されます。supportedLngsも既定値はfalseで、制限がかかりません。

もう1つ見落としやすいのが、未翻訳項目の表示を左右する既定値です。returnEmptyStringはtrueなので、翻訳管理ツールから未翻訳のまま空文字で書き出された項目は、代替言語へ切り替わらずに空欄として表示されます。翻訳が間に合わない項目を英語で埋めたいなら、この値をfalseにします。

翻訳リソースの持ち方|名前空間の分割単位とJSONファイルの配置規約

翻訳文が数百行を超えたあたりから、1ファイルでの管理は破綻し始めます。分け方の単位は、i18nextでは名前空間と呼びます。

commonと画面単位で名前空間を切り必要なファイルだけ読む設計

名前空間の説明では、共通のボタン名(common)、入力チェックの文言(validation)といった意味での分割と、画面や機能、遅延読み込みするモジュールごとの分割の両方が例に挙がっています。最初の画面で全翻訳を読み込む必要がなくなり、読み込み時間を短くできるというのが分割の理由です。

public/locales/
  ja/
    common.json      // ヘッダー・ボタンなど全画面で使う文言
    validation.json  // 入力チェックのエラー文
    checkout.json    // 購入画面だけで使う文言
  en/
    common.json
    validation.json
    checkout.json

実務では「common」と「画面単位」の2層で始め、3画面以上で使い回す文言が出たらcommonへ移す運用が回しやすい形です。別の名前空間を参照するときはt('myKey', { ns: 'validation' })と書きます。t('validation:myKey')の記法もありますが、公式は文章そのものをキーにする場合には勧めていません。

バンドル同梱とi18next-http-backendによる遅延読み込みの選び分け

翻訳ファイルの届け方は2通りです。違いは、翻訳を直したときにアプリの再ビルドが要るかどうかにあります。

届け方 翻訳修正の反映 向いている規模
resourcesでバンドルに同梱 再ビルドが必要 2言語・数百キーまで
i18next-http-backendで配信 JSONの差し替えのみ 言語や画面が多いサイト

i18next-http-backendのREADMEによると、loadPathの既定値は/locales/{{lng}}/{{ns}}.jsonで、上の配置と一致します。4.0.4ではブラウザやNode.jsの標準fetchを使う前提になっており、enginesはNode.js 18以上でした。翻訳担当者が開発者の手を借りずに文言を直す体制なら、配信方式を選びます。

複数形と補間の実装|日本語でも_otherキーが要る理由とXSS対策

英語向けの解説をなぞると、日本語のサイトで想定と違う動きをする箇所が2つあります。

CLDR規則で日本語はotherのみ|countを渡し忘れたときの表示崩れ

複数形の説明のとおり、i18nextは_oneや_otherといった接尾辞をキーに付け、countの値で文言を切り替えます。判定はIntl.PluralRulesに任せており、その元になるUnicode CLDRの複数形規則表では、日本語の区分は基数・序数ともotherの1つだけです。

// locales/ja/checkout.json
{
  "itemCount_other": "{{count}}点の商品",
  "itemCount_zero": "カートは空です"
}

// locales/en/checkout.json
{
  "itemCount_one": "{{count}} item",
  "itemCount_other": "{{count}} items",
  "itemCount_zero": "Your cart is empty"
}

// 呼び出し側(変数名は必ず count)
t('itemCount', { count: 3 });

日本語のファイルに接尾辞なしのitemCountだけを書くと、countを渡した呼び出しでは解決されません。逆にcountを渡し忘れると、接尾辞付きのキーは引かれずキー名が出ます。_zeroは言語の規則より優先される特別扱いなので、0件だけ文言を変えたい場合に使えます。v21でこの接尾辞の形式が変わっているため、古い記事のkey_pluralという書き方は今の版では動きません。

escapeValueの既定値trueとReactで二重エスケープを避ける設定

補間の説明によると、{{name}}に埋め込む値は既定でエスケープされます(escapeValueの既定値はtrue)。XSSを防ぐための既定です。ReactはJSXに渡した文字列を自前でエスケープするので、i18next側でもエスケープすると&amp;のような二重変換が画面に出ます。React連携ではinterpolation: { escapeValue: false }を指定するのが通例です。

ただし、この設定はReactのJSX経由で描画する場合に限って安全です。翻訳結果をdangerouslySetInnerHTMLやメール本文のHTMLへ入れる処理があるなら、そこでは利用者の入力を自前でエスケープします。{{- name}}のようにハイフンを付けた補間はエスケープを外す書き方で、利用者の入力を通す箇所には使いません。攻撃の仕組みはXSSとCSRFの違いと実装レベルの対策で解説しています。

SSR設計|Next.js App Routerとnext-i18next v16の構成

サーバーで描画するアプリでは、翻訳をどこで読み込み、どうやってブラウザ側へ渡すかを決める必要があります。

サーバーでgetT・クライアントでuseTを使い分けるv16の構成

next-i18nextは長くPages Router専用でした。GitHubのREADMEによると、v16でApp Routerに対応し、Server ComponentsではgetT()、Client ComponentsではuseT()を使う構成になっています。npm registryで確認した16.4.1は、Node.js 20以上とNext.js 14.1以上を要求していました。

// i18n.config.ts(プロジェクト直下)
import type { I18nConfig } from 'next-i18next/proxy';

const i18nConfig: I18nConfig = {
  supportedLngs: ['ja', 'en'],
  fallbackLng: 'ja',
  defaultNS: 'common',
  ns: ['common', 'home'],
  resourceLoader: (language, namespace) =>
    import(`./app/i18n/locales/${language}/${namespace}.json`),
};
export default i18nConfig;

// app/[lng]/page.tsx(Server Component)
import { getT } from 'next-i18next/server';

export default async function Home() {
  const { t } = await getT('home');
  return <h1>{t('title')}</h1>;
}

言語の判定とURLの振り分けは、プロジェクト直下のproxy.tsにcreateProxy(i18nConfig)を書いて行います。Next.js 16未満ではcreateMiddlewareを使うとREADMEに明記されています。ルートレイアウトでgetResources()により取り出した翻訳をI18nProviderへ渡し、ブラウザ側の再描画でも同じ文言を使う流れです。Server ComponentsとClient Componentsの境界はReact Server Componentsの使い分け、[lng]のような動的セグメントはApp Routerのファイル規約と動的ルーティングが前提知識になります。

初回描画で翻訳が欠けるSuspenseの失敗と言語別URLの必要条件

react-i18nextを直接使ってクライアントで翻訳を遅延読み込みする構成では、useSuspenseの既定値がtrueである点に注意します。<Suspense>で囲んでいないと、読み込み中の表示は空白の画面です。サーバーで翻訳済みのHTMLを返したい場面でこの構成を選ぶと、検索エンジンや初回表示に翻訳前の状態が出るため、SSRが要るページはサーバー側で読み込む構成に寄せます。

検索結果に言語ごとのページを載せたいなら、/ja/と/en/のようにURLを分けるモードを選びます。v16はCookieで言語を切り替えるモードも持っていますが、URLが1つだと言語ごとのページを検索エンジンに区別させられません。言語別URLの対応関係を伝える設定はhreflangの書き方と多言語サイトの検証手順で扱っています。

TypeScriptでの型安全化とv25からv26への移行で確かめる変更点

翻訳キーの打ち間違いは、実行するまで気づけない不具合の代表です。型で防ぐ設定と、既存アプリを上げるときの注意をまとめます。

CustomTypeOptionsで翻訳キーの打ち間違いをコンパイル時に検出

TypeScriptの説明に沿い、i18next.d.tsでCustomTypeOptionsを拡張して翻訳JSONの型を登録します。これで存在しないキーをt()に渡すとコンパイルエラーになります。

// src/i18next.d.ts
import 'i18next';
import common from '../public/locales/ja/common.json';
import validation from '../public/locales/ja/validation.json';

declare module 'i18next' {
  interface CustomTypeOptions {
    defaultNS: 'common';
    resources: {
      common: typeof common;
      validation: typeof validation;
    };
  }
}

同じ説明によると、tsconfig.jsonでstrictかstrictNullChecksを有効にしておく必要があります。キーが数千に増えてエディタの補完が重くなる場合は、enableSelectorに'optimize'を指定する選択肢も用意されています。

interpolation.formatとinitImmediateの削除とコード移行

移行ガイドが挙げるv25からv26の破壊的変更のうち、既存コードに影響しやすいのは2つです。1つはinterpolation.formatに渡していた独自の書式関数の削除で、日付や金額の整形は組み込みのFormatterにi18next.services.formatter.add()で追加する方式へ書き換えます。もう1つはinitImmediateの削除で、v24で導入されたinitAsyncへ名前を変えます。

v24からv25の変更では、changeLanguageを続けて呼んだときに順序が入れ替わる不具合が修正され、言語コードの照合方法も変わりました。複数の版をまたいで上げる場合は、版ごとに移行ガイドを読み、言語切り替えの画面を手で確かめてから次の版へ進みます。

next-intl・react-intlとの違いとi18nextを採用する条件・見送る場面

JavaScriptの国際化ライブラリは他にもあります。対応範囲と翻訳ファイルの形式を並べてから、採用の線を引きます。

i18next・next-intl・react-intl・vue-i18nの対象と形式

ライブラリ 最新版(10月22日時点) 主な対象 メッセージの書き方
i18next 26.5.4 React・Vue・Node.jsなど 独自形式(キー接尾辞)
next-intl 4.14.9 Next.js専用 ICU MessageFormat
react-intl 12.1.5 React専用 ICU MessageFormat
vue-i18n 11.4.16 Vue 3専用 独自形式

版はnpm registryのlatestタグで確認した値です。ライセンスはreact-intlだけがBSD-3-Clauseで、ほかの3つはMITでした。i18nextの強みは、同じ翻訳ファイルをフロントエンドとサーバー処理の両方で読めることにあります。メール本文やPDF帳票のようにNode.jsで生成する文面まで多言語化するなら、この差が効きます。

i18nextを採用してよい条件と別ライブラリを選ぶべき2つの場面

採用してよいのは、画面とサーバー処理の両方で翻訳を使う場合、Reactから別のフレームワークへ移る可能性がある場合、翻訳管理サービスと連携して翻訳者が直接文言を直す体制を組む場合です。どれも、翻訳の解決ロジックが1か所にまとまっている構造の利点がそのまま効きます。

見送る場面は2つあります。第一に、Next.jsのApp Routerだけで完結し、サーバー処理で翻訳を使わない新規サイト。この条件ならApp Router向けに設計されたnext-intlのほうが、設定ファイルも読み込みの仕組みも少なく済みます。第二に、Vueだけで組むアプリ。vue-i18nがVueの仕組みに沿った書き方を用意しているため、i18nextと連携パッケージを足す理由がありません。

多言語サイトの構築を外部に依頼する際に要件定義で決める翻訳運用の範囲

i18nextの導入自体は数時間で終わります。手間がかかるのは、翻訳を誰が書き、どのファイルをどの経路で更新するかという運用の部分です。外部に構築を依頼するなら、名前空間の単位、翻訳ファイルの届け方、言語別URLの有無の3点を要件定義の段階で決めておくと、公開後の文言修正で開発者が毎回呼ばれる状態を避けられます。

サイト全体の言語設計や翻訳範囲の決め方は、多言語サイト制作の進め方と言語・URL設計の判断基準で整理しています。当社では英語サイト制作・多言語サイト制作として、ライブラリの選定から翻訳の更新手順の設計まで含めた構築を受託しています。

よくある質問

i18nextの導入検討でよく挙がる疑問を、公式ドキュメントとnpm registryの記録をもとに整理します。

i18nextとi18nの違いは何ですか?

i18nは国際化(internationalization)の略語で、アプリを複数の言語や地域に対応できる構造にしておく考え方を指します。i18nextは、その考え方をJavaScriptで実装するためのライブラリの名前です。つまり、i18nが目的で、i18nextはその手段の1つにあたります。同じ目的のライブラリには、next-intlやreact-intl、vue-i18nなどもあります。

i18nextは無料で商用利用できますか?

できます。npm registryに登録されたi18next 26.5.4のライセンスはMITで、商用のアプリやサイトでの利用、改変に制約はありません。費用が発生しうるのはライブラリの外側で、翻訳管理サービスを契約する場合や、翻訳作業を外部に依頼する場合の料金が該当します。

日本語だけのサイトでもi18nextを入れる意味はありますか?

当面1言語なら、入れる必要はありません。ただし、画面の文言をコードから切り離して1か所で管理できるため、将来の英語対応が決まっている場合や、文言の修正を開発者以外が担う場合は、最初から入れておくと後の作業が減ります。導入は初期化ファイル1つとt()の呼び出しへの置き換えで済みます。

react-i18nextとnext-i18nextはどちらを使えばよいですか?

ViteなどでつくるReactの単一ページアプリなら、react-i18nextだけで足ります。Next.jsでサーバー側から翻訳済みのHTMLを返したい場合に使うのは、next-i18nextです。v16からはApp RouterとPages Routerの両方に対応しており、同じアプリで混在させる構成も扱えます。

翻訳キーは英語の文章とIDのどちらで付けるべきですか?

画面数が多いアプリでは、checkout.submitButtonのような意味を表すIDを勧めます。英語の文章をキーにすると、英語の文言を直すたびに全言語のキーを付け直す必要が出るためです。keySeparatorの既定値は.なので、文章をキーにするとピリオドで階層が分かれる不具合も起きます。

関連記事

お気に入りに入れた記事の一覧

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.07 テックブログ ファインズの不正アクセスと153万件の予約者情報|予約システムを使う店舗の報告と通知の手順
  2. 2025.08.14 コラム トラクションとは?ビジネスでの意味・指標の目安とgain tractionの使い方
  3. 2026.10.15 テックブログ 銀のさら不正アクセス:最大650万件の対象確認と窓口、パスワード変更・退会の手順
  4. 2026.10.19 テックブログ コミックシーモア不正アクセスで会員情報流出:再開時期・パスワード再設定と運営側のログ点検
  5. 2026.10.16 テックブログ バーガーキング情報漏洩どうしたらいい?約1,118万件の対象確認・補償・退会とメールの真偽

RELATED POSTS 関連記事

目次