コンテンツにスキップ
tai-kun's Blume Integrations
Esc
↑↓移動↵開く⌘Jプレビュー
このページの内容

ブラウザーの言語でルーティング

デフォルトロケールの 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 つを追加します。

  1. ミドルウェアで、デフォルトロケールの各ページの <head> に小さなインラインスクリプトを挿入します。スクリプトはページの描画前に実行され、そのページを配信している別のロケールがあれば、そのロケールの URL へ転送します。
  2. /<defaultLocale>/[...slug] のルートを追加し、ビルド時にリダイレクトページを生成します。このページは、プレフィックス付きのデフォルトロケールの URL を、プレフィックスなしの正規 URL へ転送します。

この統合は Astro や Blume の i18n 設定を変更しません。i18n.defaultLocale には i18n.locales のいずれかのコードを設定し、Blume の規則に従ってデフォルトロケールのコンテンツをコンテンツのルートに置いてください。

セットアップ

npm install @tai-kun/blume-integrations
pnpm add @tai-kun/blume-integrations
yarn add @tai-kun/blume-integrations
bun add @tai-kun/blume-integrations
nub add @tai-kun/blume-integrations
aube add @tai-kun/blume-integrations

blume.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 の設定順に並び、デフォルトロケールは常に候補に含まれます。クライアント側では次の順に転送先を決めます。

  1. ローカルストレージの blume-locale にロケールが保存されており、そのロケールがページを配信している場合は、そのロケールを選びます。Blume の言語スイッチャーで選んだ言語は、このキーに保存されます。
  2. 保存されたロケールが使えない場合は、navigator.languages を先頭から調べ、ロケールコードと完全に一致するか、ロケールコードの後ろに - が続く言語タグを探します。たとえば ja-JP は ja に一致します。
  3. 一致するものがない場合は、Blume の fallbackLocale を選びます。ただし、そのページを配信している場合に限ります。
  4. fallbackLocale が使えない場合は en を選びます。ただし、そのページを配信している場合に限ります。
  5. どれも使えない場合は、候補の先頭のロケールを選びます。
ブラウザーの言語 ページを配信するロケール 転送先
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 に含まれることを前提としています。
  • デフォルトロケール専用のコンテンツフォルダーは作りません。コンテンツのルートにあるページはデフォルトロケールのページであり、ほかのロケールはコードを名前とするフォルダーを使います。

このページは役に立ちましたか?