なぜ「ブラウザ判定」ユーティリティが業務で必要になるのか
業務システムをブラウザで動かしていると、
「Chrome では動くのに、IE だと落ちる」
「スマホの Safari だけ挙動が違う」
みたいなこと、必ず起きます。
本当は「ブラウザごとに分岐したくない」のが理想ですが、現実にはこういう場面があります。
特定ブラウザだけバグがあるので、回避コードを入れたい
古いブラウザでは、ある機能を無効化したい
モバイルかデスクトップかで UI を少し変えたい
こういうときに、
「今どのブラウザで動いているか」を知るための小さなユーティリティ
があると、コードがかなり整理されます。
ブラウザ判定の基本:navigator.userAgent を読む
userAgent 文字列とは何か
ブラウザは、自分の情報を navigator.userAgent という文字列で教えてくれます。
console.log(navigator.userAgent);
// 例: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ... Chrome/121.0.0.0 Safari/537.36"
JavaScriptこの中に、「どのブラウザか」「どの OS か」などの情報が詰まっています。
ブラウザ判定の古典的な方法は、この文字列に特定の単語が含まれているかどうかを見るやり方です。
例えば、ざっくり言うとこんな感じです。
Chrome → “Chrome” が含まれる
Firefox → “Firefox” が含まれる
Safari → “Safari” が含まれるが “Chrome” は含まれない
Edge → “Edg” が含まれる
ただし、ここには落とし穴も多いので、
「どういう前提で使うか」を理解しておくことが大事です。
シンプルなブラウザ判定ユーティリティを作る
まずは「大分類」だけ押さえる
業務でよく使うレベルの「ざっくり判定」をユーティリティにしてみます。
function detectBrowser() {
if (typeof navigator === "undefined") {
return { name: "unknown", isMobile: false };
}
const ua = navigator.userAgent;
const isAndroid = /Android/i.test(ua);
const isIOS = /iPhone|iPad|iPod/i.test(ua);
const isMobile = isAndroid || isIOS;
const isEdge = /Edg\//.test(ua);
const isChrome = /Chrome\//.test(ua) && !isEdge;
const isFirefox = /Firefox\//.test(ua);
const isSafari =
/Safari\//.test(ua) && !isChrome && !isEdge && !isFirefox;
let name = "unknown";
if (isEdge) name = "edge";
else if (isChrome) name = "chrome";
else if (isFirefox) name = "firefox";
else if (isSafari) name = "safari";
return {
name,
isMobile,
isAndroid,
isIOS,
isChrome,
isFirefox,
isSafari,
isEdge,
};
}
JavaScriptこの関数は、呼び出すと「どのブラウザか」「モバイルかどうか」などをまとめて返してくれます。
使い方はこうです。
const env = detectBrowser();
console.log(env.name); // 例: "chrome"
console.log(env.isMobile); // true / false
console.log(env.isSafari); // true / false
JavaScriptここでの重要ポイントは、
navigator がない環境(Node.js など)では “unknown” を返す
正規表現で userAgent をざっくり判定している
「Chrome だけど Edge ではない」「Safari だけど Chrome ではない」など、順番と条件を工夫している
というところです。
ブラウザ判定を「直接 if に書かない」意味
detectBrowser を挟むことでコードが読みやすくなる
ブラウザ判定を使いたくなったとき、
いきなりアプリのあちこちにこう書いてしまうと、後で地獄になります。
if (navigator.userAgent.includes("Chrome")) {
// 何かする
}
JavaScript代わりに、必ず detectBrowser を通すようにします。
const env = detectBrowser();
if (env.isSafari) {
// Safari だけの回避コード
}
if (env.isMobile) {
// モバイルだけ UI を変える
}
JavaScriptこうしておくと、
ブラウザ判定のロジックを変えたくなったとき
新しいブラウザ(例: 新 Edge)の扱いを変えたいとき
に、detectBrowser の中身だけ直せば済みます。
アプリ全体を探し回って userAgent 判定を書き換える必要がなくなります。
「生の userAgent をアプリ本体に出さない」
これが、業務コードとしての大事な設計です。
ブラウザ判定の「やりすぎ注意ポイント」
本当は「機能判定」が理想
ここで一つ、大事な考え方を共有しておきます。
「できるだけ“ブラウザ名”ではなく“機能があるかどうか”で分岐する」
というのが、モダンなフロントエンドの基本方針です。
例えば、「このブラウザは fetch が使えるか?」を知りたいとき、
本当はこう書くのが正解です。
if (typeof fetch === "function") {
// fetch を使う
} else {
// XMLHttpRequest などでフォールバック
}
JavaScriptこれを「IE だからダメ」「Chrome だから OK」とブラウザ名で判定してしまうと、
将来新しいブラウザが出たときに対応できなくなります。
なので、ブラウザ判定ユーティリティは、
特定ブラウザの既知のバグ回避
UI の微調整(モバイルかどうかなど)
のような「どうしても名前で分けたいところ」にだけ使う、
という意識を持っておくと健全です。
実務での具体的な利用イメージ
モバイルだけ UI を変える
例えば、「モバイルではモーダルではなく全画面表示にしたい」というケース。
const env = detectBrowser();
function openDialog() {
if (env.isMobile) {
openFullScreen();
} else {
openModal();
}
}
JavaScriptここでは「モバイルかどうか」だけを見ています。
Android / iOS の細かい違いは気にせず、「画面サイズや操作感が違う」ことだけを基準にしています。
Safari だけのスクロールバグ回避
例えば、「Safari だけスクロール挙動がおかしいので、特別な処理を入れたい」という場合。
const env = detectBrowser();
function setupScroll() {
if (env.isSafari) {
setupSafariWorkaround();
} else {
setupNormalScroll();
}
}
JavaScriptこうしておけば、
「Safari のバグが直ったから回避コードを消したい」となったときも、
この部分だけを見ればよくなります。
小さな練習で感覚をつかむ
ブラウザの開発者ツールを開いて、コンソールで次のように打ってみてください。
navigator.userAgent
JavaScript今あなたが使っているブラウザの userAgent がそのまま出てきます。
それを見ながら、
Chrome や Edg、Safari、Firefox がどこに入っているかAndroid や iPhone の文字がどう入っているか
を確認してみると、「正規表現でどう判定しているか」がぐっとイメージしやすくなります。
そのうえで、自分なりに detectBrowser を少しカスタマイズしてみてください。
isMac や isWindows を追加するisLegacyEdge(古い Edge)を見分けるisChromeOnAndroid のような複合条件を作る
など、「自分のプロジェクトで本当に必要な判定だけ」をユーティリティにしていくと、
ブラウザ判定が「怖いもの」ではなく、「ちゃんと設計された小さな道具」に変わっていきます。

