React Router v7でドキュメント言語を設定する方法

ブラウザとスクリーンリーダーのためにページ言語を宣言する

問題

Webページは、ブラウザと支援技術に対して主要言語を宣言する必要があります。明示的な言語宣言がない場合、スクリーンリーダーはユーザーのシステム言語をデフォルトとして使用するため、コンテンツ言語が異なる場合に誤った発音が生成される可能性があります。ブラウザは元の言語を推測する必要があるため、正確な翻訳機能を提供できません。検索エンジンは、正しい言語のオーディエンス向けにページを確実にインデックス化することが困難になり、その言語で検索するユーザーにとっての発見可能性が低下します。

解決策

ルート<html>要素にlang属性を設定して、ドキュメントの主要言語を宣言します。この属性は、コンテンツが使用する言語をブラウザ、スクリーンリーダー、検索エンジンに伝える有効な言語コードを受け入れます。言語が明示的に宣言されると、支援技術は正しい発音規則を適用でき、ブラウザは適切な翻訳オプションを提供でき、検索エンジンは適切な言語のオーディエンス向けにページをインデックス化できます。

手順

1. 現在のロケールを決定する

app/root.tsxのルートルートは、ルートHTMLドキュメントのレンダリングを担当します。アプリケーションがロケールベースのルーティング(/:locale/...パターンなど)を使用している場合は、ルートパラメータからロケールを抽出します。それ以外の場合は、デフォルトのロケールを使用します。

import { useParams } from "react-router";

export default function Root() {
  const params = useParams();
  const locale = params.locale || "en";

  return (
    <html lang={locale}>
      <head>
        <meta charSet="utf-8" />
      </head>
      <body>
        <h1>Content</h1>
      </body>
    </html>
  );
}

これは、URLからロケールを読み取り(存在する場合)、ロケールパラメータが存在しない場合は英語にフォールバックします。

2. ロケールコードを言語タグにマッピングする

アプリケーションが標準の言語タグとは異なるカスタムロケール識別子を使用している場合は、それらを有効なBCP 47言語コードに変換するマッピング関数を作成します。

function getLanguageTag(locale: string): string {
  const languageMap: Record<string, string> = {
    en: "en",
    "en-US": "en-US",
    es: "es",
    fr: "fr",
    de: "de",
    ja: "ja",
    "zh-CN": "zh-Hans",
    "zh-TW": "zh-Hant",
  };

  return languageMap[locale] || "en";
}

これにより、ルーティングで簡略化されたロケールコードを使用している場合でも、lang属性が有効な言語タグを受け取ることが保証されます。

3. HTML要素に言語タグを適用する

ルートコンポーネントの<html>要素のlang属性の値として、マッピングされた言語タグを使用します。

import { useParams } from "react-router";

function getLanguageTag(locale: string): string {
  const languageMap: Record<string, string> = {
    en: "en",
    es: "es",
    fr: "fr",
    de: "de",
  };
  return languageMap[locale] || "en";
}

export default function Root() {
  const params = useParams();
  const locale = params.locale || "en";
  const lang = getLanguageTag(locale);

  return (
    <html lang={lang}>
      <head>
        <meta charSet="utf-8" />
      </head>
      <body>
        <h1>Content</h1>
      </body>
    </html>
  );
}

lang属性は現在のロケールを反映し、ユーザーが言語固有のルート間を移動すると自動的に更新されます。