/ でのみ言語をネゴシエートし、/en/ や /fr/ のような明示的なURLでは、常に指定された言語を表示します。このガイドでは、Macのデスクトップパブリッシャー向けに、その動作の指定方法、見つけやすい文書リンクの維持方法、結果のテスト方法を説明します。

例として扱うのは、図形の配置に関する短いガイドを英語版とフランス語版で公開する、架空の公開文書コレクションです。ルートは言語選択ページで、リクエストに応じて導入文を切り替えられます。例示するすべてのアドレスは、提案する構成を示すものであり、それらのアドレスで現在ホストされているページについて述べたものではありません。

言語設定を変更する前にURLの動作を定義する

まず、簡潔なルーティング仕様を作成します。この例では、ルートで読者が言語を選び、2つの明示的なパスには翻訳済みの文書全体を配置します。Googleは言語版ごとに別々のURLを使うことを推奨し、想定した言語に基づいて読者を言語版間で自動的にリダイレクトしないよう勧めています。表示されたリンクがあれば、読者自身で選択できます。多地域・多言語サイトの管理。

リクエストされたパス 想定するレスポンス 言語設定の影響
/ 短い導入文を添えた言語セレクター 導入文と推奨リンクが変わることがある
/en/ 英語の文書全体 文書の言語は変わらない
/fr/ フランス語の文書全体 文書の言語は変わらない
未公開のパス ページが見つからないことを示すレスポンス 別の文書を黙って表示してはならない

この表を実装仕様として扱います。リクエストがルートを対象としているか確認してから、言語選択を適用してください。各ページのリクエストより先に汎用ルールを実行すると、明示的な選択が上書きされ、この仕様に反することがあります。

たとえば、/fr/ を開いた人のリクエストで英語が優先されていても、フランス語の文書を表示する必要があります。英語の優先設定は、まだ選択が決まっていない入口では役立ちますが、それ以外の場所では明示的なパスがすでに選択を示しています。この記事全体では、この優先順位を設計上の推奨として扱います。

すべてのページで、両方の言語リンクを表示します。ルートでは、推奨言語を示すことで、もう一方の選択肢を隠さずに最初の選択を簡単にできます。文書全体を載せるページでは、切り替えリンクから対応する文書へ直接移動できるようにします。

予測可能なルート言語ポリシーを選ぶ

Accept-Language は、fr;q=0.9,en;q=0.5 のような品質値とともに、レスポンスで優先される言語を示します。サーバーが要求されたすべての言語を提供しなければならないという意味ではありません。品質値がゼロなら、その言語は許容されません。Content-Language は返された表現の想定読者を示すもので、ルートを選択するものではありません。RFC 9110: HTTP Semantics、8.5、12.4.2、12.5.4節。

設定を始める前に、対応言語とフォールバックを明文化します。この例では、英語とフランス語の導入文を用意し、リクエストに使える一致候補がなければ、英語の導入文と両方の言語選択肢を表示します。このフォールバックは例示的な公開方針であり、HTTPの要件ではありません。

明示的なポリシーを備えた言語マッチングの実装を使います。RFC 4647は、filteringとlookupを区別しています。lookupは1つの結果を選び、リクエストされた範囲を優先順位順に確認し、一致を探す際にはサブタグを段階的に取り除きます。また、lookupを使うアプリケーションには、デフォルトの動作を定義するよう求めています。そのため、fr-CA のリクエストはlookupによって、対応する汎用の fr 導入文に一致することがあります。RFC 4647: Matching of Language Tags、3.4~3.4.1節。

ヘッダー内で fr や en が最初に現れる位置を検索して言語を選ばないでください。この方法では品質値や除外が考慮されません。マッチング層では優先設定を解析し、品質値ゼロの除外を考慮したうえで、文書化されたフォールバックを適用します。

ルートへのリクエスト設定 この例での想定結果
ヘッダーなし 英語の導入文と両方の選択肢
fr フランス語の導入文と両方の選択肢
fr-CA,fr;q=0.9,en;q=0.5 フランス語の導入文
en;q=0.9,fr;q=0.2 英語の導入文
de フォールバックのセレクター
fr;q=0,en;q=1 英語の導入文。フランス語は選択されない
*;q=0 明示的に定義した、未一致言語の処理

最後の行については、意図的に決める必要があります。このセレクター設計では、アプリケーションがその優先設定を受け入れないため、すべて除外されたリクエストにはフォールバックのセレクターを返すと定義します。英語が一致したと説明してはなりません。厳密なネゴシエーションが必要なら、それに対応する許容されないリクエストへのレスポンス動作を定義してテストします。いずれの場合も、ゼロを通常の低い優先度として誤って扱わないようにします。

文書の言語、リンク、検索アノテーションを一致させる

各HTML文書では、lang 属性に実際の主要言語を設定します。英語ページには en、フランス語ページには fr を設定します。WHATWGは lang を、要素の内容とテキストを含む属性の主要言語として定義しています。省略した場合は親から継承されます。URLの言語プレフィックスだけでは、この宣言は行われません。HTML Standard: The lang and xml:lang attributes。

ページ本文だけでなく、ナビゲーションリンクも確認します。WHATWG URL Standardでは、相対URLは基底URLを基準に解決されます。たとえば、別の文書基底がなければ、https://example.com/en/ からの fr/ は https://example.com/en/fr/ に解決されます。一方、/fr/ はオリジン上のフランス語パスに解決されます。表示する切り替えリンクには、意図した絶対パスを使います。URL Standard: URL writing and parsing。

検索アノテーションの目的は別です。Googleは、HTML、HTTPヘッダー、またはサイトマップを使った同等言語のアノテーションに対応しています。管理しやすい方法を1つ選んでください。各版では、自身と対応する版を完全修飾URLで示し、アノテーションを通じて互いにリンクする必要があります。ルートのセレクターは x-default の宛先にできます。ページのローカライズ版をGoogleに知らせる。

この架空のコレクションでは、アノテーションの対応関係は次のとおりです。

アノテーション 架空の宛先
en https://example.com/en/
fr https://example.com/fr/
x-default https://example.com/

公開システムがサポートするアノテーションの仕組みを使って、これらの関係を設定します。この対応表は仕様であり、実行可能なマークアップではありません。x-default はサーバーのネゴシエーションを設定せず、翻訳も提供しません。またGoogleは、hreflang やHTMLの lang を使ってページの言語を検出するのではなく、アルゴリズムで判定すると述べています。ページのローカライズ版をGoogleに知らせる。

ルートの表示切り替えとは別に、翻訳済み文書全体へ直接アクセスできるようにします。Googleによれば、クローラーは Accept-Language を送信せずにリクエストを行い、ロケールに応じて表示が変わるページでは一部の表示バリエーションが見つからない可能性があります。確実なフォールバックと直接アクセスできる言語別URLを用意すれば、クローラーにルートの異なる導入文を要求させずに、この発見性の問題に対処できます。Googleがロケール適応型ページをクロールする方法。

キャッシュされたルートレスポンスにも言語選択を反映する

ルートの選択が Accept-Language に依存する場合は、フォールバックを含むルートレスポンスに Vary: Accept-Language を含めます。既存の変化条件フィールドは維持してください。フランス語のルートレスポンスを示す例として、次のヘッダー部分を含めます。これは完全なHTTPメッセージではありません。RFC 9110: HTTP Semantics、12.5.5節。

Content-Type: text/html; charset=utf-8
Content-Language: fr
Vary: Accept-Language

RFC 9111では、保存済みレスポンスを再検証なしで再利用する前に、Vary で指定されたリクエストフィールドが一致するか、キャッシュが確認することを求めています。ルートURLが同じまま導入文が変わるため、これは重要です。Vary は選択に使う入力を記述するもので、言語マッチャーを実装するものではありません。RFC 9111: HTTP Caching、4.1節。

この設計では、/en/ と /fr/ の文書は Accept-Language によって変化しません。共有キャッシュなども含めた配信経路全体が、ルーティング仕様に従っているか確認してください。実用的な診断方法として、英語とフランス語のルートリクエストを交互に送り、その後、順番を逆にします。以前のリクエスト言語がルートから繰り返し返されるなら、キャッシュ動作とルーティングを併せて調べる必要があります。

Macから仕様をテストする

まず、公開のデモ用オリジンに架空の3ページを用意します。以下のテストを実行するには、そのオリジンに /、/en/、/fr/ のデモ用コレクションだけが含まれている必要があります。ページの作成やホストの設定は行いません。上記の例示的な example.com アドレスは、動作するテスト環境ではありません。

Macで Terminal アプリを開き、curl --version を実行してcurlが使えることを確認します。次に、以下のシェル診断スクリプト全体を貼り付けます。プロンプトが表示されたら、https:// を含むデモ用オリジンを入力してください。パスや末尾のスラッシュは付けません。

printf 'Public demo origin, without a trailing slash: '
IFS= read -r demo_origin
case "$demo_origin" in
  https://*) ;;
  *) printf 'Enter an HTTPS origin.\n' >&2; exit 1 ;;
esac

for demo_path in / /en/ /fr/; do
  for demo_language in '' 'en' 'fr' 'fr-CA,fr;q=0.9,en;q=0.5' 'en;q=0.9,fr;q=0.2' 'de' 'fr;q=0,en;q=1'; do
    printf '\nPath: %s | Accept-Language: %s\n' \
      "$demo_path" "${demo_language:-absent}"
    curl --silent --show-error --connect-timeout 5 --max-time 15 \
      --dump-header - --header "Accept-Language: $demo_language" \
      "$demo_origin$demo_path" || exit 1
  done
done

この診断では、レスポンスヘッダーと本文を出力します。curlの --header は優先設定を指定し、空の値はそのヘッダーを削除します。--dump-header - はヘッダーを標準出力に表示し、時間制限によって各転送の上限時間を設定します。予期しないリダイレクトが見えるように、リダイレクトをたどる設定は意図的に含めていません。curl — 使用方法。

このスクリプトのシェル構文は確認済みですが、デモ環境へのデプロイや、実際の言語ルーティング結果を確認したものではありません。curlの転送エラーが発生すると停止しますが、HTTPエラーレスポンスは出力されることがあるため、内容を確認する必要があります。

ルートのレスポンスを優先設定の表と照らし合わせます。次に、どのような優先設定を指定しても、すべての /en/ レスポンスに英語の内容が、すべての /fr/ レスポンスにフランス語の内容が含まれることを確認します。ステータスコード、予期しない Location フィールド、返された言語宣言、実際の文書内容を確認してください。ヘッダーが正しくても本文が誤っていれば、テストは失敗です。

最後に、両方の明示的なURLをブラウザーで開きます。各言語切り替えリンクをたどって、移動先を再読み込みし、アドレスバーを確認します。これにより、直接リクエストが成功しただけでは見つからないナビゲーションの誤りを検出できます。未公開のパスも個別にテストし、文書全体のどちらかが黙って表示されないことを確認してください。

ネゴシエーションを使えない場合は安定したセレクターを使う

この設計には、リクエストヘッダーを読み取り、レスポンスを選択できる配信層が必要です。WHATWGの文書言語とURLの仕組みは、文書とアドレスを記述するためのものです。lang 属性を追加したり、リンクテキストを変更したりしても、それだけでHTTPネゴシエーションが実現するわけではありません。リクエストに応じた選択は、HTTP配信設定で行います。HTML Standard、RFC 9110: HTTP Semantics。

公開システムにそのような配信機能がない場合は、固定されたルートセレクターを使い、各言語の文書全体へ直接リンクします。これなら読者自身が選択でき、言語ごとに別のURLを設けて切り替えリンクを表示するというGoogleの推奨にも沿います。ここでは、特定の公開製品にネゴシエーション機能があるとは想定していません。多地域・多言語サイトの管理。

実用上の合格基準は簡潔です。優先設定はルートでの選択に役立てつつ、明示的な言語リンクは確実な遷移先として維持します。フォールバックを文書化し、文書の言語宣言を一致させ、相互参照の言語アノテーションを設定したうえで、リクエストごとにルーティング仕様を満たす証拠をそろえます。

出典