LoginSignup
5
4

More than 3 years have passed since last update.

Reactで国際化対応しつつ、言語ごとにCSSを切り替えたい

Posted at

はじめに

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,
);

コンポーネント側では、FormattedMessageFormattedHTMLMessageコンポーネントを使って、

メッセージオブジェクトのキー名を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;

スクリーンショット 2019-09-28 23.06.28.png

以上が、基本的な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を切り替えられます。

スクリーンショット 2019-09-28 23.19.04.png

5
4
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
5
4