react-intlを使ってReactアプリを国際化する

react-intlを使ってReactアプリを国際化してみたところ、結構良かったので紹介します。

tl;dr

  • react-intlを使ったReactアプリの国際化方法
  • react-intlをcomponentだけではなく、utility functionとして使う方法

react-intlとは

react-intlは、Reactアプリの国際化を支援するためのComponentと幾つかのAPIを提供する、Yahoo製のライブラリです。
メッセージだけではなく数値(通貨も含む)、日付など幅広く対応しています。

今回は、メッセージの部分に特化して紹介します。

基本的な使いかた

基本的な使い方は、次の3ステップです。

  • 国際化するcontextを設定する
  • 言語設定ファイルを設定する(もし必要であれば)
  • react-intlが提供するComponent(FormattedMessage)を使ってメッセージを国際化する

国際化するcontextを設定する

まず、IntlProviderを使って国際化するためのcontextを設定します。
react-intlは、この指定したcontext配下で動作するため、アプリケーションのエントリーポイントに近い部分で行ったほうがいいです。
私の場合は、routingを設定する部分と一緒にしています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import React from "react";
import { IntlProvider } from "react-intl";
import AppRoute from "./AppRoute";

class App extends React.Component {

constructor(prop) {
super(prop);
this.state = {
locale: "ja",
message: // 実際のメッセージファイル
}
}

render() {
return (
<IntlProvider
locale={this.state.locale}
messages={this.state.messages}
>

<AppRoute />
</IntlProvider>
);

}

}

メッセージファイルについては後で説明します。

言語設定ファイルを設定する

複数言語対応する場合は、追加で言語設定ファイルを設定する必要があります。

1
2
3
4
5
6
7
import { IntlProvider, addLocaleData } from "react-intl";
import ja from "react-intl/locale-data/ja";

addLocaleData([...ja]);

// もっとたくさんの言語が必要な場合
addLocaleData([...ja, ...fr, ...es]);

Componentを使ってメッセージを国際化する

メッセージを国際化するためには、FormattedMessageを使います。

1
2
3
4
5
6
7
8
9
10
11
import { FormattedMessage } from "react-intl";

const MyComponent = () => {
return (
<div>
<FormattedMessage id="happy.birthday.to.you" />
{/* en: Happy birthday to you */}
{/* ja: お誕生日おめでとう */}
</div>
);

};

FormattedMessageidはメッセージファイルのキーと一致している必要があります。
id.で区切っていますが、これはJSONのobjectではなく純粋な文字列キーです。
そのため、上のidを指定した場合、メッセージファイルは次のようにする必要があります。

1
2
3
{
"happy.birthday.to.you": "Happy birthday to you"
}

utility functionとして使う

react-intlのComponentを利用した国際化機能は非常に強力なのですが、国際化の機能自体をpureなfunctionとして使いたいケースは結構あると思います。
例えば、次のようにComponentのpropsと一緒に利用するケースなどです。

1
2
3
4
5
6
7
8
9
10
import ChildComponent from "./ChildComponent";

const MyComponent = () => {
return (
<div>
{/* titleを国際化したい!! */}
<ChildComponent title="" />
</div>
);

};

そんな場合は、IntlProviderを直接使います。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { IntlProvider } from "react-intl";
import ChildComponent from "./ChildComponent";

const intlProvider = new IntlProvider({ locale, messages }, {});
const { intl } = intlProvider.getChildContext();

const MyComponent = () => {
return (
<div>
{/* titleを国際化したい!! */}
<ChildComponent title={intl.formatMessage({ id: "happy.birthday.to.you" })} />
{/* en: Happy birthday to you */}
{/* ja: お誕生日おめでとう */}
</div>
);

};

IntlProviderの第2引数はcontextを渡すので、特に必要なければ{}でよろしいかと。

最終的にはいろいろなComponentで利用したいので、SingletonなClassにしておくと、後で使い勝手がいいと思います。

まとめ

react-intlを使うと国際化が非常に楽です。

一工夫することで、pureなutility functionとしても使うことができるので、非常に利用用途が広い優秀なライブラリだと思います。