JavaScript でユーザーが使っているブラウザを判定したい場面は多くあります。IE 用の分岐、Safari 固有のバグ対応、モバイル / PC の出し分けなど。ただし、ブラウザ判定は最終手段であり、可能な限り機能検出(Feature Detection)を優先すべきです。
本記事では、navigator.userAgent による判定、新しい navigator.userAgentData、機能検出との使い分け、モバイル判定まで解説します。
・navigator.userAgent によるブラウザ判定
・各ブラウザの userAgent 文字列パターン
・navigator.userAgentData(User-Agent Client Hints)
・機能検出(Feature Detection)の考え方
・モバイル / PC / タブレットの判定
・iOS Safari / Chrome / Edge / Firefox の判定コード
・userAgent 詐称のリスクと対策
まず機能検出(Feature Detection)を検討する
「このブラウザだから CSS が効かない」「このブラウザだから API が使えない」という問題の多くは、ブラウザ名ではなく機能の有無で判断できます。ブラウザ判定に頼ると userAgent の変更やバージョンアップで壊れるリスクがあります。
// NG: ブラウザ名で判定
// if (navigator.userAgent.includes("Safari")) { ... }
// OK: 機能の有無で判定
if ("IntersectionObserver" in window) {
// IntersectionObserver をサポートしている
const observer = new IntersectionObserver(callback);
} else {
// フォールバック処理
}
// Service Worker のサポート判定
if ("serviceWorker" in navigator) {
navigator.serviceWorker.register("/sw.js");
}
// CSS supports() でスタイルの対応を判定
if (CSS.supports("display", "grid")) {
// CSS Grid がサポートされている
}
| 判定方法 | 推奨度 | 用途 |
|---|---|---|
| 機能検出(Feature Detection) | 最も推奨 | 特定の API / CSS がサポートされているか |
| userAgentData(Client Hints) | 推奨 | ブラウザ名・バージョンが本当に必要な場合 |
| userAgent(文字列パース) | 最終手段 | userAgentData 未対応環境でのフォールバック |
・同じ API をサポートしていてもブラウザ固有のバグがある
・アナリティクスでブラウザの利用割合を集計したい
・IE 専用の分岐が必要(非推奨ブラウザのブロック)
これらの場合にのみ userAgent / userAgentData を使ってください。
navigator.userAgent による判定
console.log(navigator.userAgent); // 例(Chrome): // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"
主要ブラウザの判定
function detectBrowser() {
const ua = navigator.userAgent;
// Edge(Chromium ベース)
if (ua.includes("Edg/")) return "Edge";
// Opera
if (ua.includes("OPR/") || ua.includes("Opera")) return "Opera";
// Chrome(Edge / Opera を先に除外してから判定)
if (ua.includes("Chrome/") && !ua.includes("Edg/") && !ua.includes("OPR/")) return "Chrome";
// Firefox
if (ua.includes("Firefox/")) return "Firefox";
// Safari(Chrome / Edge を除外した上で判定)
if (ua.includes("Safari/") && !ua.includes("Chrome")) return "Safari";
// IE 11
if (ua.includes("Trident/")) return "IE";
return "Unknown";
}
console.log(detectBrowser()); // "Chrome"
多くのブラウザの userAgent には
Chrome や Safari が含まれています(Chromium ベースのため)。Edge / Opera を先に判定してから Chrome を判定しないと、Edge を Chrome と誤判定します。userAgent に含まれるキーワード一覧
| ブラウザ | キーワード | 注意点 |
|---|---|---|
| Chrome | Chrome/ を含む | Edge / Opera も Chrome を含むため先に除外が必要 |
| Edge(Chromium) | Edg/ を含む | 旧 Edge(EdgeHTML)は Edge/ だった |
| Firefox | Firefox/ を含む | 比較的判定しやすい |
| Safari | Safari/ を含み Chrome を含まない | iOS Chrome も Safari を含むため注意 |
| Opera | OPR/ または Opera | Chromium ベース |
| IE 11 | Trident/ | IE 11 は MSIE を含まない。Trident で判定 |
| Samsung Internet | SamsungBrowser/ | Android で多いブラウザ |
navigator.userAgentData(User-Agent Client Hints)
Chrome 90+ / Edge 90+ で導入された新しい API です。userAgent 文字列のパースが不要で、構造化されたデータとしてブラウザ情報を取得できます。
// 基本情報(同期的に取得可能)
if (navigator.userAgentData) {
console.log(navigator.userAgentData.brands);
// [{ brand: "Chromium", version: "122" }, { brand: "Google Chrome", version: "122" }]
console.log(navigator.userAgentData.mobile); // false
console.log(navigator.userAgentData.platform); // "Windows"
}
// 詳細情報(非同期: Promise)
if (navigator.userAgentData) {
navigator.userAgentData.getHighEntropyValues([
"platform",
"platformVersion",
"architecture",
"model",
"fullVersionList"
]).then(data => {
console.log(data.platform); // "Windows"
console.log(data.platformVersion); // "15.0.0"
console.log(data.architecture); // "x86"
console.log(data.fullVersionList); // 詳細バージョン
});
}
| プロパティ | 内容 | 同期/非同期 |
|---|---|---|
| brands | ブラウザ名とバージョンの配列 | 同期 |
| mobile | モバイルかどうか(boolean) | 同期 |
| platform | OS 名(Windows / macOS / Android 等) | 同期 |
| platformVersion | OS バージョン | 非同期(getHighEntropyValues) |
| architecture | CPU アーキテクチャ(x86 / arm) | 非同期 |
| fullVersionList | 完全なバージョンリスト | 非同期 |
userAgentData は Chromium 系ブラウザ(Chrome / Edge / Opera)でのみ対応しています。Firefox / Safari では
navigator.userAgentData が undefined になるため、フォールバックとして userAgent も併用してください。モバイル / PC / タブレットの判定
// 方式(1): userAgentData.mobile(Chromium 系のみ)
function isMobile() {
if (navigator.userAgentData) {
return navigator.userAgentData.mobile;
}
// フォールバック: userAgent で判定
return /Android|iPhone|iPad|iPod|webOS|BlackBerry|IEMobile|Opera Mini/i.test(
navigator.userAgent
);
}
console.log(isMobile()); // true / false
// 方式(2): タッチ対応で判定
function hasTouchScreen() {
return "ontouchstart" in window || navigator.maxTouchPoints > 0;
}
// 方式(3): 画面幅で判定(レスポンシブの基準に合わせる)
function isMobileWidth() {
return window.matchMedia("(max-width: 768px)").matches;
}
| 方式 | メリット | デメリット |
|---|---|---|
| userAgentData.mobile | 正確(ブラウザが宣言) | Chromium 系のみ対応 |
| userAgent 正規表現 | 全ブラウザ対応 | userAgent 詐称で誤判定。新デバイスの追加が必要 |
| タッチ判定 | デバイスの物理能力を検出 | タッチ対応 PC(Surface 等)で誤判定 |
| 画面幅(matchMedia) | CSS のブレークポイントと統一できる | ウィンドウのリサイズで変わる |
「モバイル」が「スマートフォン」を指すのか「タッチデバイス」を指すのか「画面が小さい」を指すのかで最適な判定方法が異なります。CSS のレスポンシブ対応なら
matchMedia、タッチ操作の判定なら maxTouchPoints、OS 判定なら userAgent / userAgentData を使ってください。特定ブラウザ / OS の判定パターン
// iOS 判定(iPhone / iPod)
const isIOS = /iPhone|iPod/.test(navigator.userAgent)
|| (navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1); // iPad
// iPad 判定(iPadOS 13+ は Mac として報告される)
const isIPad = navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1;
// Android 判定
const isAndroid = /Android/i.test(navigator.userAgent);
// Windows 判定
const isWindows = navigator.userAgent.includes("Windows")
|| navigator.userAgentData?.platform === "Windows";
// macOS 判定
const isMac = navigator.userAgent.includes("Macintosh")
|| navigator.userAgentData?.platform === "macOS";
iPadOS 13 以降の Safari は userAgent に
iPad を含まず、Macintosh として報告します。iPad を判定するには navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1 の組み合わせが必要です。統合的なブラウザ情報取得関数
function getBrowserInfo() {
const info = {
browser: "Unknown",
mobile: false,
platform: "Unknown",
};
// userAgentData 優先
if (navigator.userAgentData) {
const brand = navigator.userAgentData.brands.find(
b => !b.brand.includes("Not")
);
if (brand) info.browser = brand.brand;
info.mobile = navigator.userAgentData.mobile;
info.platform = navigator.userAgentData.platform;
return info;
}
// フォールバック: userAgent
const ua = navigator.userAgent;
if (ua.includes("Edg/")) info.browser = "Edge";
else if (ua.includes("OPR/")) info.browser = "Opera";
else if (ua.includes("Chrome/")) info.browser = "Chrome";
else if (ua.includes("Firefox/")) info.browser = "Firefox";
else if (ua.includes("Safari/")) info.browser = "Safari";
else if (ua.includes("Trident/")) info.browser = "IE";
info.mobile = /Android|iPhone|iPad|iPod/i.test(ua);
if (ua.includes("Windows")) info.platform = "Windows";
else if (ua.includes("Mac")) info.platform = "macOS";
else if (ua.includes("Android")) info.platform = "Android";
else if (ua.includes("Linux")) info.platform = "Linux";
return info;
}
console.log(getBrowserInfo());
// { browser: "Chrome", mobile: false, platform: "Windows" }
実務パターン集
パターン(1): IE ユーザーに非推奨メッセージを表示
if (navigator.userAgent.includes("Trident/")) {
document.getElementById("ie-warning").hidden = false;
// "このブラウザはサポート対象外です。Chrome または Edge をお使いください。"
}
パターン(2): Safari 固有のバグ対処
// Safari の 100vh 問題(アドレスバー分がずれる)対策
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
if (isSafari) {
const vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty("--vh", `${vh}px`);
window.addEventListener("resize", () => {
const vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty("--vh", `${vh}px`);
});
}
パターン(3): アナリティクスでブラウザ情報を送信
// ブラウザ情報をアナリティクスイベントに含める
const info = getBrowserInfo();
analyticsTrack("page_view", {
browser: info.browser,
platform: info.platform,
mobile: info.mobile,
});
パターン(4): モバイルで別 UI を出し分ける
// CSS メディアクエリと統一した判定
const isMobile = window.matchMedia("(max-width: 768px)").matches;
if (isMobile) {
// モバイル用のメニューを初期化
initHamburgerMenu();
} else {
// PC 用のドロップダウンメニューを初期化
initDropdownMenu();
}
よくある質問
if (navigator.userAgentData) で存在チェックし、フォールバックを用意してください。iPad を含まず Macintosh として報告されます。navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1 で判定してください。Edg/ を含みます(末尾に e がない点に注意)。Chrome の判定より先に Edge を判定してください。Edge は Chrome のキーワードも含むため、順序を間違えると Chrome と誤判定します。matchMedia(CSS と統一)、OS / デバイスの種類を知りたいなら userAgent / userAgentData です。matchMedia はウィンドウリサイズに追従する利点がありますが、PC でブラウザ幅を狭めてもモバイルと判定されます。まとめ
ブラウザ判定の要点をまとめます。
| やりたいこと | 推奨方法 |
|---|---|
| API / CSS のサポート判定 | 機能検出(”feature” in window / CSS.supports()) |
| ブラウザ名の取得(Chromium 系) | navigator.userAgentData.brands |
| ブラウザ名の取得(全ブラウザ) | navigator.userAgent をパース(判定順序に注意) |
| モバイル判定(Chromium 系) | navigator.userAgentData.mobile |
| モバイル判定(全ブラウザ) | userAgent 正規表現 / matchMedia / maxTouchPoints |
| iPad の判定 | platform === “MacIntel” && maxTouchPoints > 1 |
| IE の判定 | navigator.userAgent.includes(“Trident/”) |
| レスポンシブ UI の切り替え | window.matchMedia(“(max-width: 768px)”) |

