言語の選び方
/ を開いた訪問者を、ブラウザが求める言語のページへリダイレクトします。
negotiate
negotiate は Accept-Language の値を読み、Locale::ALL の中から最も合う言語を返します。範囲は q の大きい順に試し、q が同じものは書かれた順に試します。範囲はまず、大文字と小文字を区別せずに範囲と等しいタグに一致します。次に、範囲の後ろのサブタグを削った形と等しいタグに一致するので、ja-JP は ja に一致します。最後に、範囲で始まるタグに一致するので、en は en-US に一致します。*、空のヘッダー、一致する言語のないヘッダーには、Locale::ALL の最初の言語を返します。
/ からのリダイレクト
axum の feature を有効にすると、redirect_to_locale は GET / に対して、言語だけをパラメータに持つルートへの 307 Temporary Redirect を返します。ブラウザによってリダイレクト先の言語が変わることがあるので、レスポンスには Vary: Accept-Language を付けます。
use axum::Router;
use hypersig_i18n::{LocaleRouterExt, negotiate};
assert_eq!(negotiate::<Lang>("ja-JP,ja;q=0.9,en;q=0.8"), Lang::Ja);
assert_eq!(negotiate::<Lang>("fr, en;q=0.5"), Lang::En);
assert_eq!(negotiate::<Lang>("de"), Lang::En);
hypersig::routes! {
fn pages(Router<()>);
const HOME: Route<Lang> = "/{lang}" => home;
}
// `GET /` answers with a redirect to `/en` or `/ja`.
let _app: Router = pages(Router::new()).redirect_to_locale(HOME);このサイトのように静的ファイルとして配信するサイトには、
Accept-Language を読むサーバーがありません。こうしたサイトでは既定の言語をルートに置き、ほかの言語へはヘッダーからリンクします。