TypeScript
React
Polyglot

React + Polyglot で多言語化対応をおこなう


はじめに

今のチームでは、多言語化対応をおこなう際、Airbnb製のライブラリであるnode-polyglotを使っています。

Reactの多言語化でポピュラーなライブラリとしてreact-intlがあります。

しかし我々の場合は、フロントエンドにReactを採用したのは最近のため、これまで利用していたライブラリを継続して使う形で開発をしています。

今回はその使い方を簡単にまとめました。


開発で用いる環境の構築

ここでは、create-react-appで環境を構築しています。

動作確認のための環境なので、 tslint のエラーが出ないように少し設定をいじっています。

tslint.jsonrulesは以下の通りです。

"rules": {

"no-var-requires": false,
"interface-name": [true, "never-prefix"],
"no-empty-interface": false,
"jsx-no-lambda": false,
"no-console": false,
"member-access": false
}


コードの実装方法

ライブラリをインポートし、変換用のファイルを読み込みます。

import * as Polyglot from 'node-polyglot';

import * as React from 'react';

const jaTranslations = require('../locales/ja.json');
const enTranslations = require('../locales/en.json');
const polyglot = new Polyglot({ phrases: jaTranslations, locale: 'ja' });
const defaultLocale = 'ja';

/***** 略 *****/

言語を切り替えるボタンを押したさいに呼ぶ関数を定義します。

引数で渡される言語によって、polyglotの locale を変更します。

それだけだと画面に再レンダリングがされないため、this.state.localeを更新しています。

(もっとうまい方法がありそうですが、探せていません)

setLocale = (locale?: string): void => {

const selectedLocale = locale || defaultLocale;

let translations = jaTranslations;
switch (selectedLocale) {
case 'ja':
translations = jaTranslations;
break;
case 'en':
translations = enTranslations;
break;
}

polyglot.locale(selectedLocale);
polyglot.replace(translations);
this.setState({ locale: selectedLocale })
};

表示は以下のように実装します。

const formStyle = {

display: 'flex',
height: 20,
justifyContent: 'space-between',
width: '50%',
} as React.CSSProperties;

return (
<div>
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
<div style={formStyle}>
<label>{polyglot.t('username')}</label>
<input type="text" />
</div>
<div style={formStyle}>
<label>{polyglot.t('email')}</label>
<input type="email" />
</div>
<div style={formStyle}>
<label>{polyglot.t('password')}</label>
<input type="password" />
</div>
<div style={formStyle}>
<label>{polyglot.t('passwordConfirm')}</label>
<input type="password" />
</div>
<div>
<button
type="submit"
onClick={e => { console.log(e); }}
>
{polyglot.t('buttonApply')}
</button>
</div>
<div>
<button
type="button"
onClick={() => { this.setLocale('ja'); }}
>
{polyglot.t('buttonJa')}
</button>
<button
type="button"
onClick={() => { this.setLocale('en'); }}
>
{polyglot.t('buttonEn')}
</button>
</div>
</div>
</div>
);


言語設定ファイル

言語設定ファイルの中身は以下の通りです。

ja.json



{
"username": "ユーザー名",
"email": "メールアドレス",
"password": "パスワード",
"passwordConfirm": "パスワード(確認)",
"buttonApply": "無料登録",
"buttonJa": "日本語",
"buttonEn": "英語",
"hello": "こんにちは"
}

en.json



{
"username": "username",
"email": "email address",
"password": "password",
"passwordConfirm": "password(confirmation)",
"buttonApply": "sign up",
"buttonJa": "Japanese",
"buttonEn": "English",
"hello": "hello"
}


実際の動作

以下のような動作になります。

polyglot_sample.gif


おわりに

コード内に直接日本語を埋め込んでしまうと、将来の運用・調査時に余計な手間を増やすことになりかねません。

日本語を直に埋め込んだケースよりも、こちらの方がコードをきれいに保つことができます。

1言語しか使わないサービスでも導入の価値はあると考えています。

もっとよいライブラリなどがあれば、ぜひ教えていただけると幸いです。