
Next.jsを多言語対応(i18n)して国際アプリにする方法
最近、vercel率いるNex.jsがアツすぎます。
とんでもない速度で開発が進み、Reactフロントエンド開発のデファクトスタンダートとなりつつあります。
今日の記事では、Next.jsを他言語化対応して、国際アプリにする方法を解説していきます。
Webサービスの他言語化対応(国際化)とは?
Webサービスの国際化とは、Webブラウザが設定してる言語や、アクセスしてきたユーザーの居住地などから、ユーザーが好む言語を検出して、自動でドメインを変えたりすることです。
例えば、アメリカ人が米国からあなたのWebサービスにアクセスしてきたら、test.en にアクセスさせて、日本人が日本からアクセスしてきたら、test.ja にアクセスさせるとか、そういうことです。
ドメインではなく、サブディレクトリで他言語化対応することもあります。 test.enではなく、 test.com/en とかにするってことですね。この設定は、サイトオーナーの好みで変わるので、決まりはありません。
Next.jsを多言語対応(国際化)するのは簡単
今までは、こういう他言語対応ってすごく面倒くさい設定を色々と実装しなきゃいけなかったんですよね。
でも、Next.jsなら、メチャクチャ簡単にこれらのことが実装できます。作業時間およそ15分ってところでしょう。
Configファイルに数行追加すれば、すぐに自動でリダイレクトされるようになります、神ですよね!
言語指定がされてないWebサイトはSEO的に最悪
Webサービスや、Webサイトの言語設定をコードでGoogleのアルゴリズムに教えることは、実はすごく大切です。
Googleのアルゴリズムは、そのサイトが誰のためのウェブサイトか知りたがっているので、メタタグとかで言語設定をするのをオススメします。
そうしないと、SEO的にすごく質の悪いウェブサイトになってしうまうので。
幸い。Next.JSでは、ページそれぞれの、ロケールを取得できるので、それに応じて、HTMLを書き換えれば良さそうです。
そうすれば、言語ごとにしっかりページがインデックスされて、ユーザーがそれぞれの検索をしたときに、別々のページが適切に検索結果に出てくるようになります。
Next.jsで他言語化対応する方法
では、前置きはこのくらいにして、早速設定をしていきましょう。
とは言っても簡単です!next.config.jsに下記のようにコードを追加してください。
ちょうど、module.exportsの下くらいに、書けばいいです。
module.exports = {
i18n: {
locales: ["en", "fr", "ja", "de"],
defaultLocale: "en",
これで、デフォルトのランゲージが英語で、それぞれ英語、フランス語、日本語、ドイツ語が追加されてることになります。
これだけで、日本からWebサイトにアクセスすれば、test.com/ja とリダイレクトされるようになるんです!
ドメインレベルの多言語をする方法
下記のコードは、Next.jsの公式の英語記事にも書いてあることです。
// next.config.js
module.exports = {
i18n: {
// These are all the locales you want to support in
// your application
locales: ['en-US', 'fr', 'nl-NL'],
// This is the default locale you want to be used when visiting
// a non-locale prefixed path e.g. `/hello`
defaultLocale: 'en-US',
// This is a list of locale domains and the default locale they
// should handle (these are only required when setting up domain routing)
// Note: subdomains must be included in the domain value to be matched e.g. "fr.example.com".
domains: [
{
domain: 'example.com',
defaultLocale: 'en-US',
},
{
domain: 'example.nl',
defaultLocale: 'nl-NL',
},
{
domain: 'example.fr',
defaultLocale: 'fr',
// an optional http field can also be used to test
// locale domains locally with http instead of https
http: true,
},
],
},
}
domainという部分に、オプションを追加すると、ドメインレベルでの他言語化になります。 つまり、上記の例であれば、下記のような感じにURLがリダイレクトされます。
example.com/blog
example.fr/blog
example.nl/blog
example.nl/nl-BE/blog
ここは、あなたのWebサイトのドメインを適応させてくださいね!
自動的にNext.jsのURL遷移を起こしたくない場合
もしかしたら、自動的に勝手にURLがレンダリングされるのが嫌な人もいるかもしれない。
そういう場合のオプションもちゃんと存在しています。
// next.config.js
module.exports = {
i18n: {
localeDetection: false,
},
}
こういう風に書きますと、勝手にリダイレクトされなくなります。
Next.jsでは、ロケール情報へのアクセスも簡単
ロケール情報へのアクセスは、Next.jsのルーター介して行います。
たとえば、useRouter()フックを使うと、以下のようなプロパティが利用できます。
- locale : 現在アクティブなロケール
- locales : 設定されているすべてのロケール
- defaultLocale : 最初に設定したデフォルトのロケール
これらを使って、データの取得を変えたりとか、ユーザーのプロフィール情報を使って画面遷移を制御したりもできますね。
まあ、画面遷移に関しては、勝手にNext.jsが面倒見てくれるので、問題ありません。このまま読み進めてください。
Next.jsの他言語対応したサイトでの画面遷移
他言語化したサイトで画面遷移するとき、next/link あるいは next/router を使用すると、しっかり言語に対応した画面遷移を行えます。
next/linkでは、locale propを指定することで、現在アクティブなロケールとは異なるロケールに移行することができますし、
ロケールのpropを指定しない場合は、クライアントの移行時に現在のアクティブなロケールが使用されます。
例えば、以下のようになります。
import Link from 'next/link'
export default function IndexPage(props) {
return (
<Link href="/another" locale="fr">
<a>To /fr/another</a>
</Link>
)
}
next/routerメソッドを直接使用する場合は、transitionオプションで使用するロケールを指定することができます。たとえば、次のようになります。
import { useRouter } from 'next/router'
export default function IndexPage(props) {
const router = useRouter()
return (
<div
onClick={() => {
router.push('/another', '/another', { locale: 'fr' })
}}
>
to /fr/another
</div>
)
}
すでにロケールを含むhrefがある場合は、ロケールのプレフィックスを自動的に処理しないようにすることができます。
import Link from 'next/link'
export default function IndexPage(props) {
return (
<Link href="/fr/another" locale={false}>
<a>To /fr/another</a>
</Link>
)
}
ちなみに、ユーザーが設定した言語を記憶させることは簡単にできる?
可能です。
Next.jsは、NEXT_LOCALE=the-localeクッキーでaccept-languageヘッダーをオーバーライドすることをサポートしています。このクッキーは、言語切り替え機能を使って設定することができ、ユーザーがサイトに戻ってきたときに、/から正しいロケールの場所にリダイレクトする際に、クッキーで指定されたロケールを利用します。
例えば、ユーザーが accept-language ヘッダで fr ロケールを選択していて、NEXT_LOCALE=en クッキーで en ロケールが設定されている場合、/ にアクセスすると、クッキーが削除されるか期限切れになるまで、ユーザーは en ロケールの場所にリダイレクトされます。