faisalman / ua-parser-js

"Unmask Your Traffic" - UAParser.js: The Essential Web Development Tool for User-Agent Detection
https://uaparser.dev/
GNU Affero General Public License v3.0
9.28k stars 1.2k forks source link

iPad recognised as macOS #671

Closed st-h closed 1 year ago

st-h commented 1 year ago

Newer iPad OS versions (in this case iPadOS 16.1.1) seem to be recognised as MacOS. Here is the full result:

{
    "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Safari/605.1.15",
    "browser": {
        "name": "Safari",
        "version": "16.1",
        "major": "16"
    },
    "cpu": {},
    "device": {
        "model": "Macintosh",
        "vendor": "Apple"
    },
    "engine": {
        "name": "WebKit",
        "version": "605.1.15"
    },
    "os": {
        "name": "macOS",
        "version": "10.15.7"
    }
bartoszhernas commented 1 year ago

Possible workaround is to check for touch device.

If it shows as macOS and it's touch enabled, then it is an iPad

const isTouchEnabled = "ontouchend" in document; // true for iPad, false for MacBook
st-h commented 1 year ago

@bartoszhernas thanks for the suggestion. Unfortunately this is used in a node environment and the only way to identify the device is via user agent. Already checking for ontouchend when run inside the browser, but that unfortunately does not work within node. I am not even sure if this can be fixed, as the user agent seems to be very similar to the MacOS user agent.

bartoszhernas commented 1 year ago

You are right, it will only work on client side. Backend side it will not be possible anymore I believe, based purely on user agent you've sent, there is nothing to distinguish if it's an iPad.

As an iPad user, I like this, as sometimes websites would show me badly made mobile versions of websites. As a developer, it's crazy if there truly is not other way to distinguish.

faisalman commented 1 year ago

Unfortunately there is still no workaround when working in node environment since it heavily relies on user-agent information.

Only after being loaded in browser it can be re-checked using withFeatureCheck() method.

// suppose this code runs on iPad
const withoutFeatureCheck = UAParser();
const withFeatureCheck = UAParser().withFeatureCheck();

console.log(withoutFeatureCheck.device); // { vendor : "Apple", model : "Macintosh", type : undefined }
console.log(withFeatureCheck.device);    // { vendor : "Apple", model : "iPad", type : "tablet" }

https://docs.uaparser.js.org/v2/api/ua-parser-js/idata/with-feature-check.html