4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-10-06

はじめに

今のチームでは、多言語化対応をおこなう際、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言語しか使わないサービスでも導入の価値はあると考えています。

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

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?