Last active
April 5, 2024 12:47
-
-
Save julienetie/af1c6cb289047cbcbdfd4b7e2f9b1492 to your computer and use it in GitHub Desktop.
Detect the operating system (os), browser and browser version without relying on depreciated ways.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const navigatorErrorMessage = 'Could not find `userAgent` or `userAgentData` window.navigator properties to set `os`, `browser` and `version`' | |
const removeExcessMozillaAndVersion = /^mozilla\/\d\.\d\W/ | |
const browserPattern = /(\w+)\/(\d+\.\d+(?:\.\d+)?(?:\.\d+)?)/g | |
const engineAndVersionPattern = /^(ver|cri|gec)/ | |
const userAgentData = window.navigator.userAgentData | |
const userAgent = window.navigator.userAgent | |
const unknown = 'Unknown' | |
const empty = '' | |
const brandList = ['chrome', 'opera', 'safari', 'edge', 'firefox'] | |
const mobiles = { | |
iphone: /iphone/, | |
ipad: /ipad|macintosh/, | |
android: /android/ | |
} | |
const desktops = { | |
windows: /win/, | |
mac: /macintosh/, | |
linux: /linux/ | |
} | |
const detectPlatform = () => { | |
if (userAgent) { | |
const ua = userAgent.toLowerCase().replace(removeExcessMozillaAndVersion, empty) | |
// Determine the operating system. | |
const mobileOS = Object.keys(mobiles).find(os => mobiles[os].test(ua) && window.navigator.maxTouchPoints >= 1) | |
const desktopOS = Object.keys(desktops).find(os => desktops[os].test(ua)) | |
const os = mobileOS || desktopOS | |
// Extract browser and version information. | |
const browserTest = ua.match(browserPattern) | |
const browserOffset = browserTest && (browserTest.length > 2 && !(engineAndVersionPattern.test(browserTest[1])) ? 1 : 0) | |
const browserResult = browserTest && browserTest[browserTest.length - 1 - (browserOffset || 0)].split('/') | |
const browser = browserResult && browserResult[0] | |
const version = browserResult && browserResult[1] | |
return { os, browser, version } | |
} else if (userAgentData) { | |
const os = userAgentData.platform.toLowerCase() | |
let platformData | |
// Extract platform brand and version information. | |
for (const agentBrand of userAgentData.brands) { | |
const agentBrandEntry = agentBrand.brand.toLowerCase() | |
const foundBrand = brandList.find(brand => { //eslint-disable-line | |
if (agentBrandEntry.includes(brand)) { | |
return brand | |
} | |
}) | |
if (foundBrand) { | |
platformData = { browser: foundBrand, version: agentBrand.version } | |
break | |
} | |
} | |
const brandVersionData = platformData || { browser: unknown, version: unknown } | |
return { os, ...brandVersionData } | |
} else { | |
// Log error message if there's a problem. | |
console | |
.error(navigatorErrorMessage) | |
return { | |
// Ignore the VSCode strikethough. Disable linting line if necessary. This is just a fallback | |
os: navigator.platform || unknown, | |
browser: unknown, | |
version: unknown | |
} | |
} | |
} | |
export default detectPlatform |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For anyone encountering problems please raise issues on https://github.com/julienetie/detect-browser
PRs are welcomed.