React Router v7でロケールベースのルーティングを実装する方法

ロケールセグメントを使用したルーティングの設定

問題

多言語アプリケーションを構築する際、すべてに影響を与える根本的な決断があります:アプリケーションはどのようにして表示する言語を判断するのでしょうか?明示的なメカニズムがなければ、URL /about はあいまいになります—どの言語のコンテンツを表しているのか不明です。ユーザーは特定の言語バージョンへのリンクを共有できず、検索エンジンもどのバージョンがどの対象ユーザー向けなのかを理解するのに苦労します。このあいまいさはユーザー体験と発見可能性の両方に問題を引き起こします。

解決策

URL パスに直接言語識別子を入れます。例えば /en/about/fr/about のようにします。これにより、すべてのパスが特定の言語に固有のものとなり、ユーザーと検索エンジンの両方にとってのあいまいさが解消されます。最初のセグメントとしてロケールパラメータを持つルートを定義することで、アプリケーションは URL からロケールを抽出し、表示する言語コンテンツを決定するために使用できます。このアプローチにより、すべての URL がページとその言語の両方を明確に識別することが保証されます。

ステップ

1. ロケールパラメータを含むルートを定義する

app/routes.ts でルートを設定し、各パスの最初のセグメントとしてロケールパラメータを含めます。

import { type RouteConfig, route, index } from "@react-router/dev/routes";

export default [
  route(":locale", "./localized-layout.tsx", [
    index("./home.tsx"),
    route("about", "./about.tsx"),
    route("contact", "./contact.tsx"),
  ]),
] satisfies RouteConfig;

コロン接頭辞により、locale は URL から解析されてルートコンポーネントにパラメータとして提供される動的セグメントになります。この設定により、/en/en/about/fr/contact のようなルートが作成され、最初のセグメントは常にロケールになります。

2. ロケールを抽出するレイアウトコンポーネントを作成する

子ルートは親ルートの Outlet コンポーネントを通じてレンダリングされます。ロケールパラメータを抽出し、ネストされたルートをレンダリングするレイアウトを作成します。

import { Outlet, useParams } from "react-router";

export default function LocalizedLayout() {
  const { locale } = useParams();

  return (
    <div>
      <nav>
        <a href={`/${locale}`}>Home</a>
        <a href={`/${locale}/about`}>About</a>
        <a href={`/${locale}/contact`}>Contact</a>
      </nav>
      <Outlet />
    </div>
  );
}

useParams フックは URL から動的セグメント値を取得します。レイアウトはこのロケールを使用してナビゲーションリンクを構築し、Outlet を介して子ルートにレンダリング制御を渡します。

3. ページコンポーネントでロケールにアクセスする

任意のルートコンポーネントでuseParamsフックを使用して、ロケールパラメータにアクセスします。

import { useParams } from "react-router";

export default function About() {
  const { locale } = useParams();

  return (
    <div>
      <h1>About Us</h1>
      <p>Current locale: {locale}</p>
    </div>
  );
}

ローカライズされたレイアウト内でレンダリングされるすべてのコンポーネントは、URLからロケールを抽出できます。この値は、適切な翻訳の読み込み、日付や数値のフォーマット、またはその他のロケール固有の判断に使用できます。

4. クライアントサイドナビゲーションにLinkコンポーネントを使用する

アンカータグをLinkコンポーネントに置き換えて、クライアントサイドルーティングによるナビゲーションを可能にします。

import { Outlet, useParams, Link } from "react-router";

export default function LocalizedLayout() {
  const { locale } = useParams();

  return (
    <div>
      <nav>
        <Link to={`/${locale}`}>Home</Link>
        <Link to={`/${locale}/about`}>About</Link>
        <Link to={`/${locale}/contact`}>Contact</Link>
      </nav>
      <Outlet />
    </div>
  );
}

Linkコンポーネントはクライアント側でルーティングを処理し、ウェブページの再読み込みを防止することで、ページ間のスムーズなナビゲーションを可能にします。各リンクには言語コンテキストをナビゲーション全体で維持するために、ロケールパラメータが含まれています。