38

The user agent of Safari on iPadOS beta is at this point exactly the same as Safari on macOS. Is there any other way to tell an iPad from a Mac?

iPad running iOS
Mozilla/5.0 (iPad; CPU OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 Mobile/14G60 Safari/602.1

iPadOS, developer beta 1
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

iPadOS, beta 2, simulator
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

iPadOS, beta 3, (simulator)
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

iPadOS, developer beta 3
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

iPadOS, developer beta 4
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

iPadOS 13.1, developer beta 1
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

iPadOS 13.1, developer beta 2
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

iPadOS 13.1, developer beta 3
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.1 Safari/605.1.15

iPadOS 13.1, developer beta 4
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.1 Safari/605.1.15

macOS Catalina 
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

macOS (older version)
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.1 Safari/605.1.15

macOS Catalina developer beta 7
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

macOS Catalina developer beta 8
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.1 Safari/605.1.15

When playing HLS video, the iPadOS agent seems to be:

AppleCoreMedia/1.0.0.17A5821e (iPad; U; CPU OS 13_1 like Mac OS X; en_us)
10
  • I'm wondering if this is actually another case of "spoofing" mentioned here. stackoverflow.com/a/7976057/129202
    – Jonny
    Commented Jun 18, 2019 at 2:46
  • In Japanese, nonetheless qiita.com/m-otoguro/items/00602315724d4a8e580c
    – Jonny
    Commented Jun 18, 2019 at 2:47
  • 2
    I added the user agent of next macOS Catalina. Note that it is EXACTLY the same as iPadOS.
    – Jonny
    Commented Jun 18, 2019 at 3:05
  • I think you just can't ??? Currently my solution is, if user-agent shows 10.15, show a pop-up ask if is iPadOS or macOS.
    – Alen Liang
    Commented Jun 24, 2019 at 4:53
  • 1
    Looking for a solution to this issue as well, and the only thing I can see that may be of use is this: Navigator.standalone From developer.mozilla.org/en-US/docs/Web/API/Navigator: "Returns a boolean indicating whether the browser is running in standalone mode. Available on Apple's iOS Safari only." Trying to get a machine with macOS 10.15 to see if it returns a value on desktop safari, but on my 10.14 macOS safari it was undefined. Returned a value in 10.15 iOS/ipadOS in my simulator Commented Jul 23, 2019 at 17:46

5 Answers 5

48

I'm using this test client side:

   if (navigator.userAgent.match(/Mac/) && navigator.maxTouchPoints && navigator.maxTouchPoints > 2) {
     ...must be iPad OS...

Since there's no official touch screen for Mac, it seems pretty safe. The actual value of maxTouchPoints on the iPad is 5, BTW.

2
  • 15
    And to those who say it shouldn't matter (use fluid webdesign!) it does matter if the user needs to either install a Safari app/extension from the Mac Store or use the iOS Share extension. I need to provide the correct link and directions.
    – user984003
    Commented Mar 18, 2020 at 20:48
  • 3
    iPad emulation on Chrome only supports 1 maxTouchPoints, so unless you don't plan on debugging using Chrome I would suggest dropping the > 2 check.
    – Nadav
    Commented Aug 4, 2020 at 6:21
13

I would not generally recommend this, and I haven't tested it much (using something similar in production since September 2019), but one way could be to detect the existence of TouchEvent on the client side, and match it with the state of the user agent to account for older iOS versions of iPad:s. YMMV. Likely not very future safe.

function isIpad() {
    const ua = window.navigator.userAgent;
    if (ua.indexOf('iPad') > -1) {
        return true;
    }

    if (ua.indexOf('Macintosh') > -1) {
        try {
            document.createEvent("TouchEvent");
            return true;
        } catch (e) {}
    }

    return false;
}
1
  • 2
    isIpad() returns true on Chrome 85 on MBP (Catalina) without touch
    – Simon B.
    Commented Oct 5, 2020 at 10:35
3

I'm using this works fine:

const ua = window.navigator.userAgent.toLowerCase();
const isiPad = ua.indexOf('ipad') > -1 || ua.indexOf('macintosh') > -1 && 'ontouchend' in document;
1
  • 1
    Checking only userAgent is NOT enough. Maybe navigator.maxTouchPoints > 2 is a good enough stop-gap fix.
    – Simon B.
    Commented Oct 5, 2020 at 10:38
2

as @Jonny mentioned you can try and detect touch events, this is the solution i currently use

function isTouchDevice() {
  if (typeof window === 'undefined') return false
  const prefixes = ' -webkit- -moz- -o- -ms- '.split(' ')
  function mq(query) {
    return typeof window !== 'undefined' && window.matchMedia(query).matches
  }
  if ('ontouchstart' in window || (window?.DocumentTouch && document instanceof DocumentTouch)) return true
  const query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('') // include the 'heartz' - https://git.io/vznFH
  return mq(query)
}

interesting post on detecting touch events

and another note, Firefox on Ipad uses the same safari user-agent :/

1
  • isTouchDevice() (May 24th version) returns true on Chrome 85 on a MBP (Catalina) without touch. Maybe navigator.maxTouchPoints > 2 is a good enough stop-gap fix.
    – Simon B.
    Commented Oct 5, 2020 at 10:39
0

If you use ua-parser-js to parse the User-Agent, you will see that iPad has "Mobile Safari" as the browser.name, while Macs have "Safari".

If the user is logged in on Chrome, parsedUA.device.model will be iPad for iPad.

The only problem seems to be on Firefox... which has "Safari" as browser.name and "Macintosh" as parsedUA.device.model for iPad...

( I am trying to rely solely on User-Agent because I'm pulling user's logged-in devices from back-end and I have no other information about the user's device )

Not the answer you're looking for? Browse other questions tagged or ask your own question.