ReactやNext.jsのサイトを多言語化する
ReactとNext.jsのi18n(多言語化)ガイド
ReactやNext.jsのサイトを多言語化する(next-intl) | We.Inc
ReactやNext.jsのサイトを正しく翻訳する方法を解説します。メッセージファイル、next-intlによるロケールのルーティング、日付、金額、複数形のIntlによる書式設定、右から左へのレイアウト、hreflangタグまで扱います。
すべての文字列を言語ごとに1つのJSONメッセージファイルにまとめ、各言語に/de/aboutのような専用のURLを割り当て、日付、価格、複数形はブラウザーに組み込まれたIntlのAPIで書式設定します。Next.jsのApp Routerでは、next-intlがこれらをつなぎます。[locale]というルートセグメント、言語を選ぶプロキシ、そしてコンポーネント内のuseTranslationsです。
翻訳されたサイトを構成する要素
- 文字列
- messages/en.json、messages/de.jsonなど
- URL
- 言語ごとに1つのパスの接頭辞:/en/...、/de/...
- 言語の検出
- proxy.ts内のnext-intlのcreateMiddleware(Next.js 16より前はmiddleware.ts)
- 日付、数値、金額
- Intl.DateTimeFormatとIntl.NumberFormat
- 複数形
- ICUメッセージ構文またはIntl.PluralRules
- 検索エンジン
- すべての言語版へのhreflangリンクと、x-default
翻訳は単語を置き換えるだけではありません。語順は変わり、複数形のルールは異なり、アラビア語は右から左に読み、日付の書き方は国ごとに違います。下の切り替えで小さな商品カードの言語が変わる様子を試し、その後、セットアップ用のファイルとhreflangジェネレーターを使って自分のアプリで同じものを作りましょう。
- デモで言語を選びます。カードのメッセージが切り替わり、価格と日付がそのロケールの書式になり、アラビア語では表示の向きが反転します。
- 商品の数を変えて、各言語がそれぞれの複数形を選ぶ様子を確認します。
- next-intlのセットアップファイルを、Next.jsのApp Routerのプロジェクトにコピーします。
- hreflangジェネレーターにドメインと言語を入力し、出力されたタグまたはmetadataオブジェクトをレイアウトに貼り付けます。
- 断片をつなげて文を組み立ててはいけません。語順は言語によって変わるため、{count}のようなプレースホルダーを使って文全体を翻訳しましょう。
- 翻訳されたラベルは英語より目に見えて長くなることが多いため、レイアウトに余裕を持たせましょう。
- すべての言語でhtml要素にlangを設定し、右から左に書く言語にはdir="rtl"を設定しましょう。
- 言語の選択肢に国旗を使うのは避けましょう。国旗は国を表すもので、多くの言語は複数の国で話されています。
- ブラウザーの設定だけに頼らず、ユーザーが手動で言語を切り替えられるようにし、その選択を記憶しましょう。
よくある質問
Reactではどのi18nライブラリを使うべきですか?
Next.jsのApp Routerには、専用に作られていてServer Componentsにも対応したnext-intlが適しています。Next.jsを使わない素のReactアプリでは、メッセージをJSONで保存するライブラリを選びましょう。そうすれば、後で別のライブラリに移行するときも扱いやすくなります。
言語はサブフォルダー、サブドメイン、別ドメインのどれに置くべきですか?
example.com/de/のようなサブフォルダーが最も運用しやすい方法です。1つのサイトと1つのドメインですべてをまかなえるからです。de.example.comや国別ドメインが必要な場合は、next-intlのドメインベースのルーティングも使えます。
Next.jsでhreflangを追加するには?
metadataまたはgenerateMetadataからalternates.languagesを返し、言語ごとのURLを1件ずつ指定します。Next.jsはそれぞれについてlink rel="alternate" hreflangタグを出力します。各言語版は他のすべての言語版と自分自身を列挙する必要があり、そうしないと検索エンジンがそのセットを無視することがあります。
サイトを機械翻訳してもよいですか?
機械翻訳を最初の下書きとして使うのは構いませんが、その言語に堪能な人に、特に見出し、価格、法的な文章を確認してもらいましょう。内容の薄い翻訳や確認されていない翻訳は、読者を混乱させ、信頼を損なうおそれがあります。
コンポーネント内の文字列ではなく、メッセージを使う
- ユーザーが目にするすべてのテキストは、Cart.checkoutButtonのように意味でキーを付けたメッセージファイルから取得すべきです。開発者は英語のファイルを、翻訳者はほかのファイルを編集し、誰もコンポーネントの中にハードコードされた文章を探し回る必要がなくなります。
- コンポーネントごとに名前空間を分けると、ファイルが読みやすくなります。next-intlのuseTranslations('Cart')を使うと、そのコンポーネント内だけでt('checkoutButton')が使えるようになります。
書式設定はIntlに任せる
- Intl.NumberFormatは、1234.5ユーロをドイツ語の読者向けに1.234,50 €と書き、記号や区切り文字をそのロケールの慣習どおりに配置します。Intl.DateTimeFormatは日付について同じことを行い、Intl.PluralRulesは、ある言語で数値がone、few、many、otherのどの形をとるかを教えてくれます。
- これらのAPIはすべての最新ブラウザーとNodeに組み込まれているため、書式設定でバンドルが重くなることはなく、自分が学んだことのない言語でも正しく表示されます。
右から左に書く言語
- アラビア語、ヘブライ語、ペルシャ語、ウルドゥー語は右から左に読みます。html要素にdir="rtl"を設定するとテキストの揃えやインライン要素の順序が反転しますが、CSSで固定したleftやrightの値はそのまま残ります。
- margin-inline-startやpadding-inline-endのような論理プロパティ、またはTailwindのms-やpe-ユーティリティを使えば、余白も向きに合わせて自動的に反転します。
App Router向けのnext-intlのセットアップ
npm install next-intlでインストールします。これらのファイルは、ロケールベースのルーティングに関するnext-intl公式の入門ガイドの構成に沿っています。
言語ごとに1ファイルで、どのファイルも同じキーを持ちます。メッセージ内の複数形はICU構文で処理します。
src/i18n/routing.tsとsrc/proxy.ts
ルーティングではロケールを1回だけ列挙します。プロキシ(Next.js 16より前はmiddleware.tsと呼ばれていました)は、訪問者を言語の接頭辞付きのパスにリダイレクトします。
src/i18n/request.ts
[locale]セグメントからロケールを読み取り、未知のロケールは拒否して、その言語のメッセージを読み込みます。
next.config.ts、レイアウト、ページ
プラグインがrequest.tsを結びつけます。ページをapp/[locale]/の下に移動し、useTranslationsでメッセージを読み込みます。next/root-paramsはNext.js 16.3からデフォルトで有効で、それより前のバージョンではexperimental.rootParamsが必要です。
ライブラリを使わない書式設定
素のJavaScriptでのIntl
翻訳の有無にかかわらず、どんなReactアプリでも使えます。
検索エンジンが確認するhreflangのルール
言語の指定を正しく行う
- 各言語版は自分自身と他のすべての言語版を列挙する
- ドイツ語のページはen、de、ar、x-defaultにリンクする
- 言語はISO 639-1、地域を付ける場合はISO 3166-1 alpha-2
- de, en-GB, pt-BR
- 地域だけを指定しない
- beはベルギーではなくベラルーシ語を指す。nl-BEまたはfr-BEを使う
- それ以外の全員にはx-default
- 言語の選択ページかメインの言語版を指す
試してみよう:1枚のカードを5つの言語で
言語を切り替え、商品の数を変えてみてください。文字列はメッセージオブジェクトから、価格、日付、複数形はブラウザーのIntlのAPIから取得しています。
言語
カート内の商品数:{n}
選ばれた複数形のカテゴリー:
向き:
このデモは通貨を換算しません。同じ数値を書式設定しているだけです。
hreflangジェネレーター
ドメイン、ページのパス、言語コードを入力すると、head用のlinkタグ、またはNext.jsのalternatesオブジェクトを取得できます。
ドメイン
ページのパス
言語コード(カンマ区切り)
x-defaultの言語
無効なコードをスキップしました:{codes}。deやen-GBのような形式を使ってください。
出力形式
HTMLのlinkタグ
Next.jsのmetadata
コピー
無料で始める · クレジットカード不要
関連: ガイド|Webマーケティングと集客を学ぶ
製品
ご利用いただける方
機能
リソース
会社情報
サイトマップを見る