March 26, 2020

Gatsby, Contentful, Netlifyで多言語ブログを作る方法 #2 - 多言語化

静的サイトジェネレーターGatsbyで作ったブログを多言語化する方法を解説。Part 2では言語切替ボタンを設置し、サイトを多言語化していきます。

Updated at November 06, 2020

Part2では、言語切替ボタンを設置し、Gatsbyで作ったサイトを多言語化していきます😀

  1. GatsbyサイトにContentfulのデータを読み込む
  2. 多言語化する
  3. ブログ記事ページを作成する
  4. Netlifyでデプロイして公開する

React-intlをセットアップ

多言語化するために、今回は react-intl というライブラリを使用します。
このライブラリは、多言語化のためのComponentやAPIを提供しているんですが、テキストだけでなく日時や数字、通貨などにも幅広く対応していて非常に便利。

プラグインをインストール

react-intlを使うため、Gatsby用のプラグインgatsby-plugin-intlをインストールします。

コマンドライン
npm install --save gatsby-plugin-intl

gatsby-config.jsに追記

追加したプラグインをgatsby-config.jsに追記します。今回はデフォルトを en にしました。

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: `en`,
    // option to redirect to `/en` when connecting `/`
    redirect: true,
  },
},

これでURLが言語によって切り替わるようになります。

言語によってちゃんと別のURLにすることは、Googleが推奨しているので従った方がいいかと👍


トップページの文言を多言語に

トップページの下記2箇所の文言を、言語によって切り替わるようにしていきます。

Formatted Message

各言語用のファイルを作成

まずは、src フォルダ直下に intl フォルダを作り、その中に en.jsonja.json ファイルを作ります。

en.json
{
  "hello": "Hi people!",
  "posts": "Posts"
}
ja.json
{
  "hello": "こんにちは!",
  "posts": "ブログ記事"
}

formatMessageで置き換える

gatsby-plugin-intl から useIntl hookを読み込み、

index.js
import { useIntl } from "gatsby-plugin-intl"

テキスト部分を書き換えます。

index.js
<h1>{intl.formatMessage({ id: "hello" })}</h1>
<h2>{intl.formatMessage({ id: "posts" })}</h2>

最終的なコードはこんな感じ。

index.js
import React from "react"
import Layout from "../components/layout"
import SEO from "../components/seo"
import { useIntl } from "gatsby-plugin-intl"

const IndexPage = ({ data }) => {
  const intl = useIntl()
  return(
  <Layout>
    <SEO title="Home" />
    <h1>{intl.formatMessage({ id: "hello" })}</h1>
    <h2>{intl.formatMessage({ id: "posts" })}</h2>
    <ul>
      {data.allContentfulBlog.nodes.map(post => {
        return (
          <li key={post.contentful_id}>{post.title}</li>
        )
      })}
    </ul>
  </Layout>
)}

export const query = graphql`
  query ContentFulBlog {
    allContentfulBlog {
      nodes {
        contentful_id
        node_locale
        title
      }
    }
  }
`

export default IndexPage

ここまで終わったら、

  • http://localhost:8000/en/
  • http://localhost:8000/ja/

それぞれの言語にアクセスすると、テキストが切り替わるのが確認できます😀


言語切替リンクを設置

Language.jsコンポーネントを作成

切替ボタン部分のコンポーネントを作るため、 src/components/Language.js ファイルを追加します。

Language.js
import React from "react"
import { IntlContextConsumer, changeLocale } from "gatsby-plugin-intl"

const languageName = {
  en: "English",
  ja: "日本語",
}

const Language = () => {
  return (
    <div>
      <IntlContextConsumer>
        {({ languages, language: currentLocale }) =>
          languages.map(language => (
            <a
              key={language}
              onClick={() => changeLocale(language)}
              style={{
                color: currentLocale === language ? `yellow` : `white`,
                margin: 10,
                textDecoration: `underline`,
                cursor: `pointer`,
              }}
            >
              {languageName[language]}
            </a>
          ))
        }
      </IntlContextConsumer>
    </div>
  )
}

export default Language

header.jsへ追加

先ほど作った <Language /> コンポーネントをヘッダーコンポーネントへ追加。

header.js
import React from "react"
import { Link } from "gatsby"
import PropTypes from "prop-types"
import Language from "./Language"

const Header = ({ siteTitle }) => (
  <header
    style={{
      background: `rebeccapurple`,
      marginBottom: `1.45rem`,
    }}
  >
    <div
      style={{
        margin: `0 auto`,
        maxWidth: 960,
        padding: `1.45rem 1.0875rem`,
        display:`flex`,
        alignItems:`center`,
        justifyContent:`space-between`
      }}
    >
      <h1 style={{ margin: 0 }}>
        <Link
          to="/"
          style={{
            color: `white`,
            textDecoration: `none`,
          }}
        >
          {siteTitle}
        </Link>
      </h1>
      <Language />
    </div>
  </header>
)

Header.propTypes = {
  siteTitle: PropTypes.string,
}

Header.defaultProps = {
  siteTitle: ``,
}

export default Header

これで、言語切替ボタンを押すと、メッセージが切り替わるのが確認できます。

Switching Languages Gif


記事タイトルを各言語のみに

GraphQLを確認

まずはGraphQL上で、試しに言語でフィルターをかけてみます。

日英どちらの記事も取得してる状態

GraphiQL

英語だけ

en でフィルターをかけます。

GraphiQL

日本語だけ

ja でフィルターをかけます。

GraphiQL

OK👍

では、上のフィルターをかけた状態のクエリをindex.jsに追加しましょう。

pageContextを確認

ブラウザのデベロッパーツールから、IndexPage コンポーネントの PageContext を見ると、language: "en" になっているのが確認できますね。日本語ページを見ている時は language: "ja" になっています。

Page Context language:

では、この language を使って、トップページのクエリにフィルターをかけていきましょう。

トップページを調整

index.js
export const query = graphql`
  query ContentFulBlog($language: String) {
    allContentfulBlog(filter: { node_locale: { eq: $language } }) {
      nodes {
        contentful_id
        node_locale
        title
      }
    }
  }
`

これで、日英どちらか一方の記事タイトルだけが表示されるようになりました🙌

EN/JA


Part2はここまで!Part3では、ブログ記事ページを作っていきます。

👋ちなみに、ここまでのコードはGitHubでも確認できます。パートごとにブランチを分けているので、よかったら参考にしてみてください😉

  1. GatsbyサイトにContentfulのデータを読み込む
  2. 多言語化する
  3. ブログ記事ページを作成する
  4. Netlifyでデプロイして公開する
高橋あゆみ

高橋あゆみ
フリーランスのUI/UXデザイナー。英語圏のロマンス・ミステリー小説にハマり、一向に減らない積読が悩み。カナダのバンクーバー在住。