Reactで簡単に多言語対応する方法は?react-i18nextの使い方
目次
はじめに
こんにちは。フロントエンドエンジニアのKimuraです。
アトラスが展開する大会事業サービスConfitは、国内大会のみではなく、国際大会でも数多くご利用いただいています。このため、各種画面は日本語のみでなく英語表示にも対応しています。
React上の多言語対応ライブラリとしては、react-i18nextがよく取り上げられるかと思います。アトラスでも、react-i18nextを利用して多言語対応を実装しています。 本記事では、react-i18nextの基本的な利用方法と、Jestによるテスト実装をご紹介いたします。
なおテストについては、公式がJest + Enzymeを利用したサンプルコードを公開しています。本記事ではそちらを参考に、React Testing Libraryを使用していきます。
利用技術
React
Create React Appを利用したTypeScriptプロジェクト上で実装を進めていきます。プロジェクトは下記のコマンドを利用して生成しています。
npx create-react-app react-i18next-sample --template typescript
react-i18next
i18nextのReact用ライブラリです。
i18nextは多言語対応ライブラリであり、react-i18nextではAPIとしてReact Hooksが提供されています。
Jest
Create React Appにデフォルトとして採用されているテスティングライブラリです。
React Testing Library
Testing Libraryが提供するReactコンポーネント用テスティングライブラリです。こちらもCreate React Appにデフォルトとして採用されています。
類似ライブラリにEnzymeがあります。
react-i18nextの利用方法
今回は、useTranslationを利用してメッセージを取得する方法を扱います。
インストール
まずは、関連するnpmパッケージをインストールします。
npm install react-i18next i18next i18next-http-backend i18next-browser-languagedetector
メッセージjson作成
言語ごとに、メッセージを定義したjsonファイルを作成します。今回は例として、日本語と英語の定義を用意します。
{
"test": {
"message": "テストメッセージ"
}
}
{
"test": {
"message": "test message"
}
}
初期化
メッセージ取得を利用する前に、初期化を実装したi18n.tsを作成します。
import i18n from 'i18next';
import Backend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
import { initReactI18next } from 'react-i18next';
i18n
.use(Backend)
.use(LanguageDetector)
.use(initReactI18next)
.init({
fallbackLng: 'ja',
ns: ['translations'],
defaultNS: 'translations',
debug: true,
interpolation: {
escapeValue: false,
}
});
export default i18n;
本記事は、React Suspenseを利用する前提の実装となります。利用しない場合は、初期化時に追加設定が必要となります。
i18n
// (中略)
.init({
// (中略)
react: {
useSuspense: false
}
});
作成したi18n.tsをindex.tsx内に読み込みます。これにより初期化が実行され、コンポーネント内でuseTranslationを利用可能となります。
import './i18n';
コンポーネント作成
実際にメッセージを取得するコンポーネントを作成します。
import React from 'react';
import { useTranslation } from 'react-i18next';
export const TestComponent = () => {
const { t } = useTranslation();
return {t('test.message')};
}
上記のコンポーネントは、<div>内にreact-i18next経由で取得した文字列を表示します。
メッセージキーをtに渡すことで、jsonファイルに定義されたメッセージが返却されます。json上の階層は.で表現されています。
App.tsx内に<TestComponent>を配置して、表示を確認してみます。
import React, { Suspense } from 'react';
import { TestComponent } from './components/TestComponent';
function App() {
return (
Loading...}>
);
}
この状態で開発サーバを立ち上げると、<TestComponent>が画面表示されます。
npm start

言語切替実装
デフォルトの日本語表示から、英語表示に切り替えるボタンを実装していきます。
import { useTranslation } from 'react-i18next';
const AppPage = () => {
const { i18n } = useTranslation();
const changeLanguage = (lng: string) => {
i18n.changeLanguage(lng);
};
return (
);
}
function App() {
return (
Loading...}>
);
}
画面を確認すると、jaとenのボタンが追加されています。これらを押下することにより、<TestComponent>の表示言語が切り替わります。

テスト
最後に、JestとReact Testing Libraryを利用してテストを実装します。
import { render } from "@testing-library/react";
import { TestComponent } from './TestComponent';
jest.mock('react-i18next', () => ({
useTranslation: () => {
return {
t: (str: string) => str,
i18n: {
changeLanguage: () => new Promise(() => {}),
},
};
},
}));
it('test render', () => {
const { getByText } = render( );
expect(getByText('test.message'));
});
モック実装が存在しない場合、実行時に警告が表示されます。react-i18nextの初期化処理が行われていないため、useTranslation()などAPIのインスタンスが取得できないことが原因です。
なお、上記のモックはtの引数をそのまま返却しています。json定義したメッセージは、コンポーネント上に表示されません。
メッセージが表示されているかを確認するため、getByTextにメッセージキー(test.messageなど)を引き渡します。これにより、任意のメッセージが出力対象となっているか検証可能となります。
下記のコマンドで、テストを実行します。
npm test src/components
最後に
react-i18next + Jest による多言語対応の実装方法、いかがでしたでしょうか。
グローバル化が進む昨今、多言語対応サービスも数多く存在しております。アトラスでも引き続き、国内外のお客様にご利用いただけるサービスを目指していきたいと思います。






