Skip to content

Instantly share code, notes, and snippets.

@julienetie
Last active April 5, 2024 12:47
Show Gist options
  • Save julienetie/af1c6cb289047cbcbdfd4b7e2f9b1492 to your computer and use it in GitHub Desktop.
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.
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
@dfahlander
Copy link

In line 27 it checks if (userAgent === false) which is defenitely never true. I suppose this gist is not updated. Is the blog entry on https://medium.com/@julienetienne/detecting-the-os-browser-and-browser-version-when-old-methods-have-depreciated-91c08a1e6407 more up-to-date than the gist?

@julienetie
Copy link
Author

In line 27 it checks if (userAgent === false) which is defenitely never true. I suppose this gist is not updated. Is the blog entry on https://medium.com/@julienetienne/detecting-the-os-browser-and-browser-version-when-old-methods-have-depreciated-91c08a1e6407 more up-to-date than the gist?

Yes you're right, that clause was there for testing purposes, it in by mistake.
The article code is the correct one, I'll update.

Thanks for the heads up.

@NatachaH
Copy link

NatachaH commented Apr 4, 2024

The Safari version is wrong for me.

My Safari version : 17.4.1 (19618.1.15.11.14)
The script return: 605.1.15

@julienetie
Copy link
Author

Thanks,
I've moved this script to a github repository. I'll look into it sometime in the week.
I may need your help testing for that particular version son.

@julienetie
Copy link
Author

For anyone encountering problems please raise issues on https://github.com/julienetie/detect-browser
PRs are welcomed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment