🤕

Gatsby Head API で react-i18next は動かない。回避方法を紹介。

2023/10/26に公開

はじめに

今のところGatsby Head APIでreact-i18nextは動きません(筆者はGatsby 5.11.0を使用)。これに対する回避方法の一つを具体的に紹介します。1章にはこちらの内容を取り扱ったGitHub issueの概要を記載しました。回避方法のみ知りたい方は2章からご覧ください。

1. Gatsby Head APIでreact-i18nextは動きません

1.1. GitHub issueの問い合わせ「動きませんよ?」

まず、この不具合について検索すると、以下のGatsbyのGitHub issueが見つかります。
Gatsby Head API with react-i18next #36458

概要は以下の通りです。こちらに記載されたコードは誤りです。

Gatsby Head APIでi18nを使用する方法を知りたいです。こちらのコードを試していますが、うまく動きません。

※このコードでは正しく多言語対応できません。
export const Head = () => {
  const { t } = useTranslation();
  return (<SEO title={t('My title')} />)
}

1.2. GitHub issueの回答「現時点では不可能です」

こちらのGitHub issueは以下の回答でcloseされています。

現在、これらのプロバイダーで Head API をラップしていないため、React Context に依存するライブラリを使用することはできません。こちら#35841 (reply in thread)を参照してください。この変更は互換性を破る変更となります。したがって、現時点では残念ながら不可能です。

1.3. GitHub issueに書かれた二つの回避方法

1.3.1. 回避方法1: 非推奨になるHelmetを使う

最初にGitHub issueに問い合わせをした方はGatsby Head APIの代わりにHelmetを使うという選択をしたようです。GatsbyとしてはHelmetの代わりにGatsby Head APIをリリースしており、Helmetは非推奨になる予定です。
https://www.gatsbyjs.com/plugins/gatsby-plugin-react-helmet/

This package will be deprecated
The gatsby-plugin-react-helmet package will be deprecated in the future. The new Gatsby Head API is easier to use, more performant, has a smaller bundle size, and supports the latest React features. Update to gatsby@^4.19.0 to use it.

1.3.2. 回避方法2: Head内でdataプロパティの言語を使って分岐する

その後、GitHub issueに以下のコメントがありました。

Headでデータプロパティの言語を抽出して分岐することができますよ。ここで使う用語はi18nのJSONファイルに定義する必要はありません。

2章でこちらの方法を具体的に紹介します。

2. Headでdataプロパティの言語で分岐して回避する方法

GitHub issueのコメントにあった回避方法を実装すると以下のようになります。dataプロパティから言語を取り出して、分岐を行います。ここで使用する用語(例では「私のタイトル」と「My title」)は、i18nのJSONファイルに定義する必要はありません。

以下の実装は1.1章で取り上げたGitHub issueの問い合わせの実装を元にしています。言語が日本語の場合には「私のタイトル」それ以外の場合には「My title」をSeoのtitleとして指定しています。

こちらが回避方法の一例です。
interface Locale {
  node: {
    ns: string;
    data: string;
    language: string;
  };
}
interface LocalesData {
  locales: {
    edges: Locale[];
  };
}

export const Head: HeadFC<LocalesData> = ({data}) => {
  const lang = data.locales.edges[0].node.language;
  const myTitle = lang === 'ja' ? '私のタイトル' : 'My title';
  return (<SEO title={myTitle} />)
}

おわりに

記事を読んでいただいてありがとうございました。実際に私もGatsby Head APIでreact-i18nextによる多言語対応をしようとしてこの問題に遭遇し、GitHub issueを読みながら回避を行いました。同じように困った方のお役に立てれば幸いです。

以下がこの記事の方法でGatsby Head APIの不具合を回避した筆者のWebアプリです。Headに記載したOGPの情報が日本語と英語で表示されているのが確認できると思います。是非以下のリンクからWebアプリにも訪問してみてください。
https://zozooizozzoizioiiiooi-dots.onrender.com/
https://zozooizozzoizioiiiooi-dots.onrender.com/en

Discussion