確かに簡単すぎたが、静的ページのみの構成では...
こちらの記事がまとまっていてとてもわかりやすかったので、これをもとに導入しようとしたら、記事のタイトルにあるように本当に簡単すぎて3時間ぐらいでi18n対応(日本語対応)ができました。
NextLink の遷移先も特に何も考えずによしなに対応してくれて、便利!
しかし、SSGモードで Amplify にデプロイしようとしたら build エラー!
Error: i18n support is not compatible with next export
あれ、公式にSSG対応について書いてあるはずなのに...
と疑問に思い色々見てみると、どうも SSG/SSR のハイブリッドでホスティングしている場合のSSGページの対応方法が記載されているだけらしく、
next export
でプリレンダリングしてホスティングしている場合には対応していないようです。
(基本は SSR でホスティングしていないとダメ)
next-export-i18n
同じところで悩んでいる方はいるようで、結構対応が大変そうだなと思っていたのですが、この記事↑のコメント欄に next export
に対応したライブラリ作ったよとのコメントがありました。
これは確かに簡単そうで、元々の i18n の ja.ts ファイルも流用できそう。
しかも、実装例まであってとてもわかりやすい!
例がこれです↑
移行しよう
↑の記事の実装から移行する場合、基本的には以下を
import { useLocale } from "@/hooks/use-locale"
const { t } = useLocale()
t.SIGNUP
以下のように書き換えればOK
import { useTranslation } from "next-export-i18n"
const { t } = useTranslation()
t('SIGN_UP')
それに加えて少しパヤパヤしないといけませんが、対応するところは以下
- アプリルートに i18n というディレクトリを作って、locale用のファイルをjsonファイルで作成して置く
- ページ遷移時にクエリパラメータを追加する
- 言語切り替え用のボタンなどを作成する
import NextLink from 'next/link'
import { useLanguageQuery } from "next-export-i18n";
export const TitleLabel = () => {
const [query] = useLanguageQuery();
return (
<NextLink href={{pathname: "/", query: query}} passHref>
title
</NextLink>
)
}
import { LanguageSwitcher } from 'next-export-i18n';
const ChangeLangButton = (id, name) => {
return (
<LanguageSwitcher lang={id}> // 例えば lang={"en"} のようになるようにする
<Button>
{ name }
</Button>
</LanguageSwitcher>
)
}
設定ファイルに useBrowserDefault: true
を設定すると、ブラウザのデフォルトの言語が自動的に適用されます。これは便利!
var en = require('./translations.de.json');
var de = require('./translations.de.json')
const i18n = {
translations: {
en: en.i18n,
de: de.i18n,
},
defaultLang: 'de',
useBrowserDefault: true, // これ
}
module.exports = i18n;
時間はかかった
状態管理に jotai を使っていて、ステートをURLと同期させていたのでうまく動かないか心配しましたが、その点もクリアでした!
なぜ next export
でできないのかとか、他の実装方法がないか調べたり、実際に移行作業したり動作確認したりで、1日潰れました笑
同じ轍を踏むような人がでないために、備忘録としてここに記しておきます