ブラウザーの言語でルーティング
デフォルトロケールの URL を、訪問者のブラウザー言語に合うロケールへ転送します。
routeByBrowserLanguage() は、Blume の i18n が持つルーティングをそのまま使う Astro 統合です。デフォルトロケールはプレフィックスなしで配信されます。訪問者のブラウザーが英語を優先する場合、統合は /guide のようなデフォルトロケールのページを /en/guide へ転送します。デフォルトロケールを優先する場合は /guide のまま表示します。
できること
- ローカルストレージの
blume-localeに保存されたロケールがそのページを配信している場合は、そのロケールへ転送します。Blume の言語スイッチャーで選んだ言語が保存されており、ブラウザーの言語設定より優先されます。 - 保存されたロケールが使えない場合は、ブラウザーの言語設定(
navigator.languages)を先頭から調べ、一致するロケールへ転送します。ja-JPはjaに一致します。 - どちらにも一致する言語がない場合は、そのページを配信している範囲で、Blume のフォールバックロケール、
en、候補の先頭の順に選びます。 /ja/guideのようなデフォルトロケールのプレフィックス付きの別名 URL を、正規の/guideへ転送します。そのあと、正規のページでブラウザー言語による転送が実行されます。/en/guideのようなほかのロケールの URL はそのままにします。- クエリ文字列と URL フラグメントを引き継ぎます。
仕組み
この統合は、Blume の i18n を設定したサイトに次の 2 つを追加します。
- ミドルウェアで、デフォルトロケールの各ページの
<head>に小さなインラインスクリプトを挿入します。スクリプトはページの描画前に実行され、そのページを配信している別のロケールがあれば、そのロケールの URL へ転送します。 /<defaultLocale>/[...slug]のルートを追加し、ビルド時にリダイレクトページを生成します。このページは、プレフィックス付きのデフォルトロケールの URL を、プレフィックスなしの正規 URL へ転送します。
この統合は Astro や Blume の i18n 設定を変更しません。i18n.defaultLocale には i18n.locales のいずれかのコードを設定し、Blume の規則に従ってデフォルトロケールのコンテンツをコンテンツのルートに置いてください。
セットアップ
npm install @tai-kun/blume-integrationspnpm add @tai-kun/blume-integrationsyarn add @tai-kun/blume-integrationsbun add @tai-kun/blume-integrationsnub add @tai-kun/blume-integrationsaube add @tai-kun/blume-integrationsblume.config.ts の integrations に統合を追加し、Blume の i18n に実際のデフォルトロケールを設定します。
import { routeByBrowserLanguage } from "@tai-kun/blume-integrations";
import { defineConfig } from "blume";
export default defineConfig({
integrations: [routeByBrowserLanguage()],
i18n: {
defaultLocale: "ja",
locales: [
{ code: "ja", label: "日本語" },
{ code: "en", label: "English" },
],
},
});
defaultLocale には、locales に含まれるいずれかのコードを設定します。プレースホルダーのロケールを追加する必要はありません。
コンテンツの配置
デフォルトロケールのページはコンテンツのルートに置きます。それ以外のロケールは、コードを名前とするトップレベルのフォルダーに置きます。
content/
index.mdx
guide.mdx
en/
index.mdx
guide.mdx
defaultLocale: "ja" の場合、Blume は content/index.mdx を / で、content/en/index.mdx を /en で配信します。日本語が優先される場合、/ と /guide へのアクセスは日本語のページを表示します。英語が優先される場合は、/en と /en/guide へ転送します。
動作確認
ビルドしたサイトで、/guide のようなデフォルトロケールの URL を開きます。ブラウザーの言語設定に一致するロケール、または Blume の言語スイッチャーで最後に選んだ言語のページへ転送されれば成功です。言語の選択が保存されていない場合、ブラウザーの言語設定を変えると、選ばれるロケールも変わります。
/ja/guide も開いてみてください。デフォルトロケールの正規 URL である /guide へ転送されます。
転送先の選び方
転送先の候補は、そのページを配信しているロケールだけです。候補は i18n.locales の設定順に並び、デフォルトロケールは常に候補に含まれます。クライアント側では次の順に転送先を決めます。
- ローカルストレージの
blume-localeにロケールが保存されており、そのロケールがページを配信している場合は、そのロケールを選びます。Blume の言語スイッチャーで選んだ言語は、このキーに保存されます。 - 保存されたロケールが使えない場合は、
navigator.languagesを先頭から調べ、ロケールコードと完全に一致するか、ロケールコードの後ろに-が続く言語タグを探します。たとえばja-JPはjaに一致します。 - 一致するものがない場合は、Blume の
fallbackLocaleを選びます。ただし、そのページを配信している場合に限ります。 fallbackLocaleが使えない場合はenを選びます。ただし、そのページを配信している場合に限ります。- どれも使えない場合は、候補の先頭のロケールを選びます。
| ブラウザーの言語 | ページを配信するロケール | 転送先 |
|---|---|---|
ja-JP |
ja、en |
/guide |
en-US |
ja、en |
/en/guide |
fr-FR |
ja、en |
fallbackLocale が en なら /en/guide |
fr-FR |
ja のみ |
/guide |
転送では window.location.replace() を使うため、元の URL はブラウザーの履歴に残りません。この統合は言語の選択を保存しません。保存するのは Blume の言語スイッチャーだけです。ストレージが使えない環境では保存されたロケールを読めないため、ブラウザーの言語設定から選びます。
リダイレクトの対象
ブラウザー言語による転送は、デフォルトロケールのページだけで実行します。サイドバーで非表示にしたページ(sidebar.hidden: true または hidden: true)は転送しません。ほかのロケールの URL は転送しないため、明示的に開いた /en/guide は英語のまま表示されます。
デフォルトロケールのプレフィックス付きの別名 URL は、表示されているすべてのデフォルトロケールのページに対して作成します。バージョン付きの URL にも対応します。/ja/v1/guide は /v1/guide へ転送され、そのページでもブラウザー言語による転送が実行されます。デプロイ先のベースパスと Blume の basePath も転送先に含まれます。
JavaScript を実行しない場合
デフォルトロケールのページは、実際に生成された通常のページです。JavaScript を実行できない場合、訪問者は言語による転送を受けず、デフォルトロケールのコンテンツをそのまま閲覧します。
プレフィックス付きの別名ページ(/ja/…)は転送専用のページです。JavaScript を実行できない場合に備えて、正規のデフォルトロケールのページをリンクとして表示します。AI エージェントやクローラーも、このリンクからページへ到達できます。
API
| エクスポート | 型 | 説明 |
|---|---|---|
routeByBrowserLanguage |
() => AstroIntegration |
統合を作成します。 |
注意点
- ブラウザー言語による転送はクライアント側の JavaScript で実行するため、初回表示時にデフォルトロケールのページが一瞬表示されることがあります。別名ページは最初の 1 秒間、内容を非表示にしてちらつきを防ぎます。
- 生成されるのは静的な HTML です。サーバー側で言語を判定するわけではありません。
- この統合は Blume の i18n データを使い、
defaultLocaleが設定済みのlocalesに含まれることを前提としています。 - デフォルトロケール専用のコンテンツフォルダーは作りません。コンテンツのルートにあるページはデフォルトロケールのページであり、ほかのロケールはコードを名前とするフォルダーを使います。