はじめに
Reactで国際化対応する場合は、react-intlが有名です。
react-intlで国際化対応しつつ、言語ごとにCSSをカスタマイズする必要があったので、
現状どうやっているかをメモとして残します。
react-intlの基本的な使い方
日本語と英語に対応する場合の、react-intlの基本的な使い方です。
まず、日本語と英語のメッセージをオブジェクトとして定義しておきます。
messages.js
const messages_ja = {
"app.input.username.label": "ユーザ名",
"app.input.username.description": "10文字以内で、半角文字の数字、大文字英字、またはアンダースコアで入力してください。",
};
const messages_en = {
"app.input.username.label": "Username",
"app.input.username.description": "Username must be within 10 characters and can only include numbers, capital letters or underscores.",
};
export default {ja: messages_ja, en: messages_en};
アプリ初期化時に、IntlProvider
にブラウザの言語設定と言語に対応するメッセージオブジェクトを渡して、トップレベルのコンポーネントを包みます。
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {IntlProvider} from 'react-intl';
import messages from './i18n/messages';
const rootElement = document.getElementById('root');
// 言語設定が日本語ならjaを、それ以外ならenを使う
const language = window.navigator.language.substring(0, 2) === 'ja' ? 'ja' : 'en';
ReactDOM.render(
<IntlProvider locale={language} messages={messages[language]}>
<App/>
</IntlProvider>,
rootElement,
);
コンポーネント側では、FormattedMessage
やFormattedHTMLMessage
コンポーネントを使って、
メッセージオブジェクトのキー名をid
として指定します。
App.js
import React from 'react';
import {FormattedMessage} from "react-intl";
import './App.css';
function App() {
return (
<div className="App">
<label>
<FormattedMessage id="app.input.username.label"/>
<input type="text"/>
</label>
<div className="description"><FormattedMessage id="app.input.username.description"/></div>
</div>
);
}
export default App;
以上が、基本的なreact-intlの使い方です。
言語ごとにCSSを切り替える
ReactをrenderするDOM要素に対して、lang属性を指定してあげます。
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {IntlProvider} from 'react-intl';
import messages from './i18n/messages';
const rootElement = document.getElementById('root');
// 言語設定が日本語ならjaを、それ以外ならenを使う
const language = window.navigator.language.substring(0, 2) === 'ja' ? 'ja' : 'en';
// rootのDOM要素にlang属性を指定する。
rootElement.setAttribute('lang', language);
ReactDOM.render(
<IntlProvider locale={language} messages={messages[language]}>
<App/>
</IntlProvider>,
rootElement,
);
CSS側では、lang擬似クラスを使って言語固有のCSSを定義します。
/* root要素には、言語によらないか、大多数の言語で必要になるCSSを定義する */
#root {
word-break: normal;
}
/* 言語ごとに個別に指定したいCSSがある場合は、lang擬似クラスを使って定義する */
#root:lang(ja) {
word-break: break-word;
}
コンポーネント側で細かく言語ごとにCSSを切り替えたい場合も、同じようにlang擬似クラスを使用します。
.App .description {
font-size: 14px;
color: #777;
}
/* 言語が日本語の場合だけ効く */
.App .description:lang(ja) {
color: #dc7a00;
}
このようにlang属性、lang擬似クラスを使うことで、CSSを切り替えられます。