こんにちは、
この記事はReact Nativeアドベントカレンダーの10日目の記事です。
弊社のアプリに取り入れたlocizeとi18nextの組み合わせが結構いい感じだったので紹介しますね。
サンプルコードはこちらです。
https://github.com/tsukushi0104/react-native-expo-locize-example
背景
弊社のサービスはユーザの半数以上が外国人ユーザであり、i18n対応はかなり重要です。しかしこれまで各言語に応じた翻訳ファイルは通常のアプリのソースと一緒にgitで管理されており、簡単な文言修正でも開発者が修正する必要がありました。
簡単な修正なのですがコストは発生しますし、何よりも文言を変更したい方からするとわざわざエンジニアにお願いしなければならないという部分で少し億劫になるのかな、と感じていました。
これで何が楽になるのか
エンジニアにとって
- i18nを含む文言修正全般の業務を翻訳チームやデザイナーに甘える事ができる。
翻訳チームにとって
- 強力な翻訳ダッシュボードを獲得できる(検索、バージョン管理、進捗管理 etc..)
- 翻訳チームだけで多言語対応可能になる
デザイナーにとって
- 文言修正を自分のエンジニア抜き、自分のペースで行うことができる
手順
i18nextを組み込む。
# npm
$ npm install i18next --save
# yarn
$ yarn add i18next
初期化処理
import i18next from 'i18next';
export default async () => i18next.init({
lng: 'ja',
debug: true,
resources: {
en: {
translation: {
"key": "hello world"
}
},
ja: {
translation: {
"key": "おはよう、ワールド"
}
}
}}
);
次に、jsxの中に i18next.t('key')
とすれば、、
import i18next from 'i18next'
{...}
<Text>{i18next.t('key')}</Text>

「おはよう、ワールド」が表示されます。なんの驚きもありませんね。
translationファイルを別ファイルにする事もできますが、このままだと文言修正コストがかかってしまいます。次で一気にlocizeを導入しちゃいましょう。
locize導入
- locizeにアクセス
- アカウント作成は無料なのでよしなに登録してください。
- 「Create Demo Project」をクリックしてみてください。
- そうすると、「en, de, it」の3言語がデモ用で作成されます。
- 「ADD NEW LANGUAGE」をクリックしてjaを追加してみてください。
- 日本語が進捗0の状態で作成されます。
locizeとアプリをつなぐ
i18next-locize-backendを利用します。
# npm
$ npm install i18next-locize-backend --save
# yarn
$ yarn add i18next-locize-backend
initI18next.jsにて、言語ファイルをlocizeから取得するように修正します。
import i18next from 'i18next';
import LocizeBackend from 'i18next-locize-backend';
export default (callback) => i18next
.use(LocizeBackend)
.init({
lng: 'ja',
debug: true,
fallbackLng: {
// lngに指定した言語が翻訳されていない場合に参照する言語
default: ['en']
},
// locizeに登録されているnamespace。demoの場合はtranslation
defaultNS: 'translation',
backend: {
// locizeのプロジェクトIDです
projectId: 'your project id',
// saveMissingがtrueの時に必要です。
apiKey: 'your api kei',
// locizeで設定されているreferenceLngを指定してください。saveMissingがtrueのときに必要です。
referenceLng: 'en',
// locizeのどのバージョンの言語を取得するのかを指定します。デフォルトはlatestです
version: 'latest',
},
}, callback
);
projectId
と apiKey
はlocizeのSettingページから確認できます。
ひとまず、これで最低限のつなぎこみは完了です。
この状態で expo start
すると「おはよう、ワールド」が「key」になっているかと思います。当然です、locizeの中に 'key' というキーに紐づいている言語はありません。
locizeにキーを登録する
- locizeにログインしてプロジェクトを選択してください。
- Reference Languageであるenのパネルを選択してください
- メニューバーの 「ADD KEY」をクリックしてください
- Keyに
key
、Value
に 適当な文言を入力して画面上部から愉快なアニメーションで出てくるSaveをクリックしてください。 - そうするとreference Languageに新規にキーが追加された事でitとdeの進捗が98%になりました。このように、各言語の進捗がわかりやすい、というのがlocizeの一つのメリットです。
- なお、今は
fallbackLng
がen
なので、この状態でexpoをフリフリすれば文言が「Key」から「Value」になっています! -
ja
のパネルから日本語のkey
の値を適当な日本語にして保存、expoフリフリすればもちろん文言が変更されます!

端末からlocaleを自動取得する
今はi18nextの初期化の時に ja
を指定していますが、これを端末の言語を使うようにすることもできます。
{...}
import { Localization } from 'expo-localization';
import _ from 'lodash';
import subtag from 'subtag';
export default (callback) => i18next
// languageDetectorを追加
.use({
type: 'languageDetector',
async: true, // flags below detection to be async
detect: (callback: string => void) =>
// 端末から取得出来るlocale情報とlocizeの言語タグに違いがあるのでそのギャップを埋める
Localization.getLocalizationAsync().then(({ locale }) => {
const { language, script } = subtag(locale);
callback(_.concat([language, script]).filter(Boolean).join('-'));
}),
init: () => {},
cacheUserLanguage: () => {},
})
{...}
終わりに
実際に端末の言語設定を変更していただければ、その言語をちゃんと読み込んで動作しているはずです。
いかがでしょうか?locizeとi18nextを組み込むことで エンジニアを飛び越えてi18n対応を含む文言修正が出来るアプリを作り上げることが出来る! ということが伝わりましたでしょうか。。?
こちらにサンプルソースを置きましたのでlocizeに登録の上、体験してみてください。
この記事では紹介ができませんでしたが、これとstorybookも組み合わせるとかなり効率的に翻訳作業を進めることが出来ます。こちらについても近いうちに記事をかければ。。。
明日はハムカツおじさんの記事です。楽しみですね。