あいつの日誌β

働きながら旅しています。

i18next を使って国際化してみる

github.com

あらすじ

とあるサイトの開発に携わっているのですが、将来的に国際化して海外ユーザーもターゲットとしたい。という話なので予め国際化する準備をしておきたい。

最初は react-intl を試そうとしましたが、どうやら react-helmet との相性があんまり良くなさそう。使えるんだけどインターフェースが複雑。

そんな訳で次に react-i18next を試そうと思ったのですが、そもそも i18next の使い方を覚えたほうがいいなと思ったので練習しました。

やりたい事

  • 日本語、英語に切り分けたい
  • `{t('key')} と書いたらいい感じになる
  • {t('key', 引数)} のように引数を渡したい
  • t('some.key)}` のよう書きたい

将来的に国際化したいのですがいきなりそこまで頑張りたくもないです。なんですが Form Validation のところだけは最初から国際化したいのでそこだけ頑張りたいです。

どうせサーバーサイドとのやりとりでエラー文言は英語になるだろうし...

just do it

create-react-app practice-i18next && cd $_
mkdir -p locales/{en,ja}
touch locales/{en,ja}/translation.json
yarn add i18next --save

create locales/en/translation.json

{
  "hello": "hello",
  "world": "world",
  "welcome": "welcome, {{name}}!!",
  "validation": {
    "isNotEmail": "{{email}} is not valid email."
  }
}

create locales/ja/translation.json

{
  "hello": "こんにちは",
  "world": "世界",
  "welcome": "ようこそ, {{name}}さん!!",
  "validation": {
    "isNotEmail": "{{email}} は正しい形式ではありません"
  }
}

edit src/App.js

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

import i18next from 'i18next';
import enLocalesTranslationJson from './locales/en/translation'
import jaLocalesTranslationJson from './locales/ja/translation'

i18next
  .init({
    fallbackLng: 'ja',
    debug: true,
    resources: {
      en: {
        translation: enLocalesTranslationJson
      },
      ja: {
        translation: jaLocalesTranslationJson
      }
    }
  });

class App extends Component {
  render() {
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Welcome to React</h2>
        </div>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
         <h2>{i18next.t('hello')}</h2>
         <h2>{i18next.t('world')}</h2>
         <h2>{i18next.t('welcome', {name: "田中"})}</h2>
         <h2 style={{color: "red"}}>{i18next.t('validation.isNotEmail', {email: "tanaka@"})}</h2>
      </div>
    );
  }
}

export default App;

動作確認

yarn start

f:id:okamuuu:20170922194126p:plain

まとめ

react-i18next という公式な react 向けの wrapper があるようですが、なんだか i18next で事足りる気がする。react-i18next を使ったほうがいいのかは後々考える事にします。