/** * Coarse device/browser classification from the User-Agent header. No * library, no raw UA string ever stored - just one bucket per request, * computed on the fly and discarded after classification. Not meant to be * precise (e.g. WebView vs. real browser); good enough for the "device * type" / "browser" breakdown in the Analytics dashboard. */ export type DeviceType = "mobile" | "desktop" | "tablet"; export type BrowserFamily = "chrome" | "firefox" | "safari" | "edge" | "other"; export function classifyDevice(userAgent: string): DeviceType { const ua = userAgent.toLowerCase(); if (/ipad|tablet(?!.*mobile)|(android(?!.*mobile))/.test(ua)) return "tablet"; if (/mobi|iphone|ipod|android/.test(ua)) return "mobile"; return "desktop"; } export function classifyBrowser(userAgent: string): BrowserFamily { const ua = userAgent.toLowerCase(); // Order matters: Edge/Chrome UAs also contain "safari"; Chrome UAs also // contain "chrome" but so do Edge/Opera - check the most specific tokens first. if (/edg\//.test(ua)) return "edge"; if (/chrome\/|crios\//.test(ua)) return "chrome"; if (/firefox\/|fxios\//.test(ua)) return "firefox"; if (/safari\//.test(ua)) return "safari"; return "other"; }