Gatsby.js で i18n 対応をする際に、gatsby-plugin-intl を使ってみたので導入手順をメモしておきます。
インストール
公式サイト(https://www.gatsbyjs.com/plugins/gatsby-plugin-intl/)に従ってインストールします。
npm install --save gatsby-plugin-intl
次に、gatsby-config.js を編集します。プラグインのところに以下を追加します。
{
resolve: `gatsby-plugin-intl`,
options: {
// language JSON resource path
path: `${__dirname}/src/intl`,
// supported language
languages: [`en`, `ja`],
// language file path
defaultLanguage: `ja`,
// option to redirect to `/ja` when connecting `/`
redirect: false,
},
},
リダイレクト設定は、ルートパス「/」にアクセスした時に defaultLanguage のパスである「/ja」にリダイレクトするかどうかになります。
言語別ファイルを作る
/src/intl
というディレクトリを作成し、その中にen.json
とja.json
の2つのファイルを新規に作成します。
そして、それぞれ英語と日本語変換したときの文章を入れていきます。
// ja.json
{
"title": "日本語サイト",
"description": "こちらは日本語ですよ。",
"category": {
"home": "ホーム",
"blog": "ブログ",
}
}
// en.json
{
"title": "English site",
"description": "This page is in English",
"category": {
"home": "home",
"blog": "blog",
}
}
"category"
のところのように、JSON をネストしてグループ化しておくことも出来ます。
実際に使ってみる
実際にコンポーネントやページの中で使ってみます。
// index.js
import React from 'react'
import { useIntl, Link } from 'gatsby-plugin-intl'
const IndexPage = () => {
const intl = useIntl()
return (
<Layout>
<SEO title={intl.formatMessage({ id: 'title' })} />
<h3>{intl.formatMessage({ id: 'title' })}</h3>
<p>{intl.formatMessage({ id: 'description' })}</p>
<Link to="/blog/">{intl.formatMessage({ id: 'category.blog' })}</Link>
</Layout>
)
}
export default IndexPage
useIntl
とLink
をgatsby-plugin-intl
からインポートします。Link はgatsby
のものがあったら削除して、gatsby-plugin-intl
を使うようにします。そうしないと、言語別に自動でルーティングしてくれる機能が使えません。
次に言語の切り替えボタンを実装します。コンポーネントとして、components/language.js
を作り、このように実装しました。
// components/language.js
import React from 'react'
import { IntlContextConsumer, changeLocale } from 'gatsby-plugin-intl'
const languageName = {
ja: '日本語',
en: 'English',
}
const Language = () => {
return (
<div>
<IntlContextConsumer>
{({ languages, language: currentLocale }) =>
languages.map(language => (
<a
key={language}
onClick={() => changeLocale(language)}
className={
currentLocale === language
? `font-bold underline cursor-pointer mx-2`
: `none cursor-pointer mx-2`
}
>
{languageName[language]}
</a>
))
}
</IntlContextConsumer>
</div>
)
}
export default Language
changeLocale
関数を使って言語変換をします。上のコンポーネントはこんな感じになります。(className のところは現在のロケールを自動で判別して太字にする処理が書いてあります。なお、tailwindCSS という CSS フレームワークを使ってます。)
出来上がったコンポーネントはこんな感じです。
これで完成!
これで、日本語の場合は、「/ja」配下にページが作成され、英語の場合は「/en」配下にページが生成され、changeLocale()の関数を叩かない限り、ロケールは変更されなくなります。
非常にシンプルに実装できるのはありがたいですね。
以上です。