Next.js(ページルーター)v16でロケールベースのルーティングを実装する方法

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

問題

多言語アプリケーションを構築する際、すべてに影響を与える根本的な決断があります:アプリケーションはどのようにして表示する言語を判断するのでしょうか?明示的なメカニズムがなければ、URL /about はあいまいになります—どの言語のコンテンツを表すのかわかりません。ユーザーは特定の言語バージョンへのリンクを共有できず、検索エンジンはどのバージョンがどの対象者向けなのかを理解するのに苦労します。このあいまいさは、特定の言語でコンテンツを識別またはブックマークする明確な方法がないため、ユーザーエクスペリエンスとSEOの両方に問題を引き起こします。

解決策

Next.jsの組み込みi18nルーティングサポートを設定して、URL パスに直接言語識別子を配置します。Next.js設定でサポートしたいロケールとデフォルトロケールを宣言します。Next.jsは自動的にルーティングを処理し、/fr/about/nl-NL/aboutのようなパスを利用可能にします。一方、デフォルトロケールにはプレフィックスがありません。これにより、すべてのパスが特定の言語に固有のものとなり、ユーザーと検索エンジンの両方にとってのあいまいさが解消されます。

ステップ

1. next.config.jsにi18n設定を追加する

next.config.jsファイルにi18n設定を追加して、アプリケーションがサポートするロケールを宣言します。

module.exports = {
  i18n: {
    locales: ["en-US", "fr", "nl-NL"],
    defaultLocale: "en-US",
  },
};

ロケールはUTSロケール識別子で、言語、地域、スクリプトをダッシュで区切った標準化された形式です。defaultLocaleは、ロケールプレフィックスのないパスを訪問する際に使用されます。

2. ページでロケール情報にアクセスする

useRouter()フックを使用して、ページコンポーネントでロケール情報にアクセスします。

import { useRouter } from "next/router";

export default function AboutPage() {
  const router = useRouter();
  const { locale, locales, defaultLocale } = router;

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

localeプロパティには現在アクティブなロケールが含まれ、localesには設定されたすべてのロケールが含まれ、defaultLocaleには設定されたデフォルトロケールが含まれています。

3. データ取得関数でロケールにアクセスする

getStaticPropsまたはgetServerSidePropsでページをプリレンダリングする場合、ロケール情報はコンテキストで提供されます。

import { GetStaticProps } from "next";

export const getStaticProps: GetStaticProps = async (context) => {
  const { locale } = context;

  const messages = await import(`../messages/${locale}.json`);

  return {
    props: {
      messages: messages.default,
    },
  };
};

これにより、アクティブなロケールに基づいてビルド時またはリクエスト時にロケール固有のデータを読み込むことができます。

4. ロケール間のリンク

locale propを持つnext/linkを使用して、異なるロケールに遷移します。

import Link from "next/link";

export default function LanguageSwitcher() {
  return (
    <nav>
      <Link href="/about" locale="en-US">
        English
      </Link>
      <Link href="/about" locale="fr">
        Français
      </Link>
      <Link href="/about" locale="nl-NL">
        Nederlands
      </Link>
    </nav>
  );
}

locale propが提供されていない場合、クライアント遷移中に現在アクティブなロケールが使用されます。locale propを使用すると、ユーザーは同じ論理ページにとどまりながら言語を切り替えることができます。

5. すべてのロケールの静的パスを生成する

getStaticPathsを活用する場合、設定されたロケールはコンテキストパラメータのlocalesの下に、設定されたデフォルトロケールはdefaultLocaleの下に提供されます。

import { GetStaticPaths } from "next";

export const getStaticPaths: GetStaticPaths = async (context) => {
  const { locales } = context;

  const paths = locales.flatMap((locale) => [
    { params: { slug: "getting-started" }, locale },
    { params: { slug: "advanced" }, locale },
  ]);

  return {
    paths,
    fallback: false,
  };
};

これにより、動的ページのすべてのロケールバージョンがビルド時にプリレンダリングされます。