Next.jsのSGで多言語(i18n)対応しようとしてハマった話
はじめに
個人で開発している便利ツールの Web サイトの多言語対応(国際化やi18nともいう)をしたときの備忘録。Next.js の SG で対応言語ごとにページをわけて Web ページを生成するのは大変だった。
Next.jsで多言語対応する方法は大きく分けて二つ
Webサイトの国際化対応は大きく分けて2つの方法がある
- メイン言語のページをレンダリング時にJSで文字列を置き換える
- 対応言語ごとにページを作成する
一つ目の方法は以下の記事のように react-i18next を使えばわりと簡単に実装できる。[1]開発をはじめた当初はこちらのアプローチで実装していた。
ただしこの文字列置き換えはメインの言語情報以外は検索エンジンに登録されないためSEO的に良くない。特にメタタグまわりがメイン言語でしか生成できないのが難点。SEOも含めてちゃんと対応するのであれば対応言語ごとにページを用意するのが良い。
Next.jsで対応言語ごとにページを生成する方法
Next.js で対応言語ごとにページを生成するのであれば next-i18next を使うのが定石。実装方法は以下の記事が参考になる
next-i18nextはnext exportに対応してなかった
ここからが本題、 next-i18next を使った多言語対応、SSR や Vercel にデプロイするのであれば問題なく動作するが、Firebase や Netlify、GitHub Pagesにデプロイする場合はうまくいかない。next export
を実行すると以下のエラーが出て静的サイトの生成に失敗する。
i18n support is not compatible with next export.
Next.js の公式ページを確認すると next export は国際化に対応していないことが書かれていた(どうやら今後の対応予定もなさそう)。
Note that Internationalized Routing does not integrate with next export as next export does not leverage the Next.js routing layer. Hybrid Next.js applications that do not use next export are fully supported.
next exportのエラー回避策
国際化対応で next export のエラー回避策は以下
- react-i18nextを使って文字列置き換えをする
- SGやめてSSRにする
- Vercelにデプロイする
- next-i18nextではなくnext-export-i18nを使う
- 独自実装する
上の3つはここまでに説明した内容の繰り返し、下の2つについて。
next-export-i18nを使う
next-export-i18n は next export コマンドに対応した Next.js 向けのライブラリ。一見良さそうな印象ではあるもの、対応言語ごとにページを分けるのではなくページにクエリパラメータを渡す方式を採用している。なので SEO 対策が不十分(メタタグの多言語対応ができなさそう)。SEO気にしないなら素直に react-i18next を使って文字列置き換えをした方が良い。
独自実装する
next-i18next を使わずに i18next を使って独自実装する方法。以下の記事が参考になった。
どちらのアプローチも実装が少々複雑になるので採用には至らず。
結局Gatsbyに乗り換えた
最終的に Gatsby に乗り換えることにした。そもそも SG(Static Generation) がしたかっただけでSSRやIVRの機能を使いたかったわけでなく、今後も使う予定もなかった。SG(Gatsby的にはSSG?) に特化した Gatsby の方が技術要件的にあってるなと判断。Gatsby だと gatsby-node.ts にページ生成時の処理を独自に実装できるのでそのあたりも乗り換える動機になった。
-
リンクの記事は Gatsby を使うことが前提になっているが Next.js(SG) でもほぼ同じ実装で問題なく動作する(検証済み)。 ↩︎
Discussion