- 著者
- app-hacks
- 公開日
- 更新日
- 確認日
JavaScript / i18n / UX
強制リダイレクトしないブラウザ言語案内の実装
ブラウザ言語を判定し、非モーダルな言語案内とlocalStorageで利用者の選択を尊重する実装を解説します。
強制リダイレクトしないブラウザ言語案内の実装
多言語サイトでブラウザ言語を検出すると、利用者を別言語URLへ自動移動させたくなることがあります。しかし、ブラウザの優先言語は、利用者がいま開いたURLより優先される命令ではありません。共有リンク、ブックマーク、検索結果、翻訳の比較など、現在のURLを選んだ理由があります。
このサイトでは、ブラウザ言語を案内の表示条件としてだけ使い、ページ移動は利用者がリンクを選んだときだけ行います。
強制リダイレクトを避ける理由
自動リダイレクトは、英語環境の利用者を日本語URLから離したり、言語版を比較したい利用者を戻したりします。URLを共有した相手と表示中のURLが異なることもあります。別言語版があることを知らせるのは有用ですが、現在のURLを置き換える必要はありません。
非モーダルな案内と通常の言語リンクなら、対応版を示しながら、読者が現在の言語で読み続ける選択を残せます。
対応している言語だけを判定する
ブラウザは優先言語を配列で返すことがあります。先頭の一件だけではなく順番に調べ、サイトが対応している言語だけを採用します。
type SupportedLanguage = 'ja' | 'en';
function getPreferredSupportedLanguage(): SupportedLanguage | null {
const candidates = navigator.languages?.length
? navigator.languages
: [navigator.language];
for (const candidate of candidates) {
const language = candidate.toLowerCase().split('-')[0];
if (language === 'ja' || language === 'en') return language;
}
return null;
}
en-USやen-GBのような地域付きの値は、最初の-より前の言語部分で判定します。対応外の言語はnullとして扱い、推測で別の言語へ移動させません。
表示判定と遷移を分ける
日本語ページで英語が優先され、英語版が存在するときだけ、英語版へのリンクを案内できます。
const preferred = getPreferredSupportedLanguage();
const shouldOfferEnglish =
currentLanguage === 'ja' && preferred === 'en' && hasEnglishVersion;
ここで行うのは表示判定だけです。location.hrefやlocation.replace()で移動させません。利用者がリンクを押したときだけ通常のページ遷移を行うため、戻る操作、共有URL、明示的な言語選択を尊重できます。
選択を安全に保存する
同じ案内を毎回表示しないために、選んだ言語を保存する場合があります。保存する値はjaかenのような最小限の選択に限定し、ストレージが使えない環境でもページを壊さないようにします。
function readLanguageChoice(): SupportedLanguage | null {
try {
const value = localStorage.getItem('app-hacks.language');
return value === 'ja' || value === 'en' ? value : null;
} catch {
return null;
}
}
この値は表示の好みであり、認証情報、メールアドレス、行動履歴を保存する場所ではありません。ストレージを拒否するブラウザでも、案内が出ないだけで本文と通常の言語リンクは使えるべきです。
実装後の確認項目
日英それぞれのページで、対応する言語リンクが正しいURLを指すことを確認します。英語版がないページには案内を出さず、保存済みの選択がある場合も不要なバナーを繰り返さないことを確認します。JavaScriptを無効にしても、通常の言語リンクから移動できる構成を残します。
ブラウザ言語は補助情報として使い、URLの選択権は利用者へ残す。この分離により、多言語案内を追加しても既存URLと利用者の意図を壊さずに済みます。