Detecting a mobile browser
Asked Answered
A

47

1315

I'm looking for a function that returns a boolean value if the user is using a mobile browser or not.

I know that I can use navigator.userAgent and write that function by using regex, but user-agents are too various for different platforms. I doubt that matching all possible devices would be easy, and I think this problem has been solved many times so there should be some kind of complete solution for such a task.

I was looking at this site, but sadly the script is so cryptic that I have no idea how to use it for my purpose, which is to create a function that returns true/false.

Autarky answered 8/7, 2012 at 8:13 Comment(16)
Related: #3515284.Hypolimnion
Try reading this. #743629Power
It would be better if server did this and sent across different versions of JS file..Coyle
@Thrustmaster: It really wouldn't. Serving different JS to different browsers means you have to add Vary: User-Agent to your response, otherwise caching proxies will store one version and send it to the other kind of browser. But Vary: User-Agent makes the response uncachable in IE.Tupiguarani
@ave: What are you trying to do by detecting a "mobile" browser? The distinction is highly arguable in today's world of tablets and hybrid computing devices. Are you looking to detect small screens, and present a different UI in that case? Are you looking to detect low-bandwidth connectivity? Are you looking to detect touch interfaces?Tupiguarani
@Tupiguarani Thanks for that. Every single day I get to learn something new at SO! :)Coyle
So i've updated my answer to use the detectmobilebrowsers.com javascript method but return a boolean value if anyone still needs this. ( just in case ). Happy Detecting :)Segal
@Autarky : Just to throw in another way of thinking. I find it's easier to detect devices based on screen size in today's world of multiple portable devices. Using something like Harvey.js you can basically Media Query your JS.Nisbet
@bob I came here and the reason why I need this is that I want to enable a background video. Mobiles and tablets stop autoplay of the video and it really shows there is a step too far between them STILL. But I echo your reasoning as today I feel this gap should not be there. After all RWD is based on this premise.Landel
It's generally regarded that it is better to feature detect rather than browser detect these daysHippie
@Tupiguarani Maybe "mobile" browser means touchable and small screen?Hyperphysical
Most of the time ask isMobile is a weak question... what you do with this information? preferer a strategy of feature detection. such have screen size less than XXX? Have Bluetooth? have a touch screen? and so on... Use the user agent information to detect it's also a weak feature that could be outdated and fail in some cases.Brake
Just use the css media query, specify min-width and max-width. It's overkill to classify the userAgent.Bodleian
For React users: react-device-detectDurwyn
@Autarky I strongly lobby toward re-selection of a correct answer for this popular topic. userAgent string detection is fraught with problems and superior strategies such as feature detection have existed since your initial question almost 10y ago. Let's not lead people astray; better to lead to better/modern solutions. Thanks!Bode
try navigator.userAgentData. if(navigator.userAgentData) // only available in computer browser. If true then it opened from computer browser with developer console opened. If false then it opened from mobile device since mobile device browser doesn't have navigator.userAgentDataSwabber
S
1806

Using Regex (from detectmobilebrowsers.com):

Here's a function that uses an insanely long and comprehensive regex which returns a true or false value depending on whether or not the user is browsing with a mobile.

window.mobileCheck = function() {
  let check = false;
  (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
  return check;
};

For those wishing to include tablets in this test (though arguably, you shouldn't), you can use the following function:

window.mobileAndTabletCheck = function() {
  let check = false;
  (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
  return check;
};

Using navigator.userAgentData

You may also use navigator.userAgentData.mobile, but userAgentData is still experimental, so it is not recommended for use in production.

const isMobile = navigator.userAgentData.mobile; //resolves true/false

Compatibility chart for userAgentData


The Original Answer

You can do this by simply running through a list of devices and checking if the useragent matches anything like so:

  function detectMob() {
    const toMatch = [
        /Android/i,
        /webOS/i,
        /iPhone/i,
        /iPad/i,
        /iPod/i,
        /BlackBerry/i,
        /Windows Phone/i
    ];
    
    return toMatch.some((toMatchItem) => {
        return navigator.userAgent.match(toMatchItem);
    });
}

However since you believe that this method is unreliable, You could assume that any device that had a resolution of 800x600 or less was a mobile device too, narrowing your target even more (although these days many mobile devices have much greater resolutions than this)

i.e

  function detectMob() {
    return ( ( window.innerWidth <= 800 ) && ( window.innerHeight <= 600 ) );
  }

Reference:

Segal answered 8/7, 2012 at 8:24 Comment(58)
Hi I just visited the detectmobilebrowsers.com link on my iPad 3, iOS 6.1.2, and it says "No mobile browser detected".Eboni
@RichardLovejoy when building sites, the ipad is generally not considered a mobile.Segal
Thanks for shedding some light , the latest version on detectmobilebrowsers.com looks slightly different in that it takes the site it redirects to if mobile as parameter to the annonymouse functionPanhellenic
@Panhellenic indeed they've mixed some stuff up however the regex hasn't changed since October last year so the above code is still up to date :)Segal
From the about page: Android tablets, iPads, Kindle Fires and PlayBooks are not detected by design. To add support for tablets, add |android|ipad|playbook|silk to the first regex.Analysis
Google TV is Android too. What define a mobile ? Screen Size ? Touch ? deviceOrientation ? When i design it's more a question of mousehover or not, big bouton or small links. So, for now, i run with "if (Modernizr.touch)" :)Skolnik
The question is not "How should I go about detecting a mobile browser?" but "how can i get a boolean return from a function such as that which i saw on detectmobilebrowsers.com?"..not really understanding the downvotes but okaySegal
Gawd, this whole idea of user agents is awful and really, really needs to stop. We really need to stop allowing clients to fight against the tide and just stick with media queries. If they want to do redirects based on scale for particular pages, then just check the range of a particular media query via JS i.e. tylergaw.com/articles/reacting-to-media-queries-in-javascriptPlaygoer
@ChristopherFrancisco I wish I could take credit for it hahahaSegal
That website is not detecting my Nokia Lumia 928 (Windows Phone) as being a mobile device, despite it have an iemobile check. Anyone know a workaround?Envision
@DoubleGras Would you mind showing where exactly to add that? Thank you so much in advance!Err
In each code, there are 2 regexes: the first one checks in the whole user agent, the second one only checks the first 4 characters. Add the provided fragment to the first regex, like so, as of today: ...|xda|xiino|android|ipad|playbook|silk/iAnalysis
For those who say we should just rely on media queries, this often doesn't cut it. For example, I have a website that plays HTM5 audio, and mobile browsers don't behave the same as they do on desktop browsers; such as iOS requiring user interaction before playing audio. These sorts of things can't be detected by media queries, nor by Modernizr.Bromo
@Playgoer You seem to be approaching this from a web design perspective, but in the realm of web applications, it's not uncommon at all to have to confine yourself to arbitrary business rules regarding how things display on mobile browsers regardless of screen size.Slake
I know, but that's still the problem.Playgoer
The updated regex fails in iBooks on iPad. Returns false. The original response returns true.Countermand
Hi @rharriso, I've just updated the script with the latest regex. Let me know if it works iBooks now.Segal
@MichaelZaporozhets, I just ran again through the inspector. Still the function above still returns false. Below is the useragent. "Mozilla/5.0 (iPad; CPU OS 8_0_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12A405 Safari/600.1.4"Countermand
@Countermand Ah sorry, I didn't notice that you were on an iPad in the first comment. Please read the 1st and 2nd comments on this comment thread.Segal
@MichaelZaporozhets. difference of opinion then. I'll stick with the original regex then.Countermand
@Countermand I think i'll just write an alternate version that covers iPads too, given the demand.Segal
What does the "b" in function(a, b) stands for? you are clearly sending only one argument to the functionScrofula
why not find the size of screen instead from here and here or media queries in css or media queries in javascriptBianchi
This won't work on a nexus 7 tablet because the user agent doesn't include the "mobile" keyword after Android, while it does on an Android smartphone. The regex (android|bb\d+|meego).+mobile requires that android be followed by one or more of anything and then "mobile" which is not the case on tablet. Thus the comment from @GrasDouble to resolve the issue on various tablet types. However it might be more efficient to put android|ipad|playbook|silk| at the start of the 1st regexp instead of at the end.Prophets
@user2005009 I've added a function that will include tablets to the answer.Segal
I've read through all the comments. Would it not be better to detect its a mobile device by testing the default "click event". For example, query screen size is not good enough for me, because I need to serve a different experience based on whether the user is using their fingers or a mouse. Is this possible? Edit: It appears it could be #4817529End
how to check if the device are touchscreen ?Compander
@MichaelZaporozhets I realise you just copied it from detectmobilebrowsers.com, but I'm almost tempted to downvote this because of the unmaintainability of that code. It's not just the horific regexes, but why have it wrapped all in a self executing function and why not have a sensibly named variable? Why is it just 'a'?Unshakable
@Unshakable Don't shoot the messenger! DMB does it this way (I presume they have an automated compilation script that pushes out the latest 'combination' or so which you have 'a' as the variable. One could of course change this, but maintaining any other updates apart from the return response each update from DMB simply doesn't seem worth my time.Segal
thanks for tablet, it's very usefull ! For me what to do "mobile" is not size, but touchscreen because a lot of css feature like "hover" on menu or tooltip have no sense without a mouse even if the screen is 4000px widthColligan
Nice Code! I agree that using Javascript to do this is can be painful and requires updating for new devices/browsers on the market, but at at this moment in time I would say use Javascript. Choosing CSS media queries can attempt to detect mobile/tablet but would still require updating for new devices. I would prefer using Javascript since I can keep the mobile/tablet detection code in one place and be able to do anything I need with Javascript code (including modifying the CSS). If you think you found better Javascript code, please share. Btw, is this code being kept up to date?Talmud
hi is this function up to date? window.mobileAndTabletcheck = function() {Chapa
Can someone explains how this function works? How is check being updated?Bullion
It uses the closure property for the check variable, and sets if if the if statement is true. There's probably better ways to write this.Japheth
That regex is some dangerous stuff you've got there. You could poke someone's eye out with that thing!Zahara
Not expecting this to change I opted to make it more static without a function call. It could be done where window.mobileCheck is a boolean that the comprehensive line makes true.Lingo
this method is such a mess, why not just have it return a boolean value??Francesco
@Francesco it... does?Segal
@MichaelZaporozhets im talking about the self executing function after var check = falseFrancesco
@Francesco ah yeah- honestly, I'm pretty sure I left that in there to 'show working' from the source. That being said- no need for it stay that ugly now. feel free to suggest an edit. Probably time for an es6 version too tbh.Segal
Hello, from the future. Now even the 2K resolution is not unique on mobiles, so please refrain using that as a check.Flintshire
I read detectmob as detectmobster and for a second I thought you were policeBlacking
+1 for checking dimensions. I realized the reason I wanted to detect mobile in the first place was to accommodate smaller screen widths.Piassava
To use window.mobilecheck, you need to use it as window.mobilecheck(). Why is it a function and not a boolean variable?Nachison
@Mth see o.p: "I'm looking for a function..."Segal
I get it. The question says he wants a function that returns a boolean variable. Anyways, thanks for the function!Nachison
I know you are just offering it as an alternative; but why not use window.screen.width and window.screen.height to capture the device screen size instead of window.innerWidth and window.innerHeight? This way the function won't detect a false screen size when the browser is not full screen. I tested this and it works reliably on Chrome 71, Safari 12, Firefox 64, Edge 18, IE11, Android (Chrome and Firefox), iPhone and iPad (Safari and Chrome for both).Freezer
Detecting chrome in Mac as mobile deviceSaltation
Do not rely on window.innerWidth for detecting mobile devices. It may give suprisingly large number if the site has elements larger than window width and mobile browser automatically scales the page. Instead use document.body.offsetWidth or window.screen.widthAnxious
Note that chrome is deprecating navigator.userAgent 9to5google.com/2020/01/14/…Dewclaw
window.mobileAndTabletCheck function does not detect my iPad ProHarleyharli
@BelowtheRadar Unfortunately iPad Pro Safari does not identify itself as a tablet or mobile device, which disables this method of identification. If you're looking to target the ipad and similar devices, I'd probably look at browser api sniffing methods instead. See this answer for further information #57776501Segal
"No mobile browser detected" for iPad Air 2 on detectmobilebrowsers.comMittel
better to use window.screen.width because if the window is not maximized you will get a "wrong" answerParotid
Careful there is an extra | in mobileAndTabletCheck regex which makes the whole test wrong. Tried to edit but it's under 6 characters, so i can't. Any mod ?Matthias
Agent strings will be spoofed. 2022 and long before, feature detection is far superior and reliable. Mandalorians would say, "userAgent is Not the way."Bode
what will be result of function detectMob if android laptop comes to marketObsequies
I wonder now in 2023 which is the current right way to do thisRabkin
T
375

How about:

if (typeof screen.orientation !== 'undefined') { ... }

...since smartphones usually support this property and desktop browsers don't. See in MDN.

EDIT 1: As @Gajus pointed out, window.orientation is now deprecated and shouldn't be used.

EDIT 2: You can use the experimental screen.orientation instead of the deprecated window.orientation. See in MDN.

EDIT 3: Changed from window.orientation to screen.orientation

Tracytrade answered 13/1, 2013 at 8:24 Comment(29)
this is actually super unique and awesome, do you mind if I add it to my answer?Segal
thank you for the compliment. of course i don't mind. i didn't tested it though, so i would love to get some implementation feedbacksTracytrade
This is probably not going to work for long. 1) Tablets can have decent screen sizes, you want them to display full desktop website but they will have this property 2) Windows 8 is here and with it a bunch of laptops with touch screen and screens that rotate.Dhoti
as for your first point about Tablets with decent screen sizes- I think you could make the same arguments for all others solutions as well (a tablet with big screen that is been tracked as small screen). anyway the idea here is to search for property that is been shared by small devices instead of keep maintence long code and add regex with every new coming device/vesion/model. I think device detection is belong to the past and today we need to focus on feature detection. again I will be glad to here about more suitable property for that matter...Tracytrade
Simple solution to a complex problem. I like it!Dallis
Love it and works perfectly, thankyou. For my solution I was just after simple.Doubletongued
I'd take care with this approach. It seems not to be supported thoroughly, just by iOS and some Android devices.Mylander
I just tested this on an iPhone (iOS 7) and it works if the device is in landscape orientation, but not portrait.Turino
this varient if(window.orientation !== undefined) {...} should be enoughTripartition
I prefer this, not for full fledged mobile detection. But as a helper work around to the limited orientation support on desktop. The accepted answer is also risky, if that list isn't up to date the function won't work across all browsers. And given its regex nature the chances of someone maintaining it are slim. This option is clear, short, succinct FTWParonychia
I tried different browsers on the same Android 4.4.4 device: Chrome - OK; Firefox - Not working; Dolphin - OK.Seventh
I only need to detect a mobile device on my site to determine weither to use touchstart events or click events; the breakpoints are all irrelevant of window size and put in place to ensure the site is formatted nicely. so for a solution to detect weither or not I want touch events (any phone or tablet) or click events (a laptop / desktop) this is an awesome solution. thanks so much; the regex answers were complex and require constant maintenance.Abebi
I like this solution because it answers the question of "is this mobile" as simply as possible. The question isn't "how do I detect small screen sizes", but rather "Detecting a mobile browser."Anthelion
window.orientation is a deprecated property (developer.mozilla.org/en-US/docs/Web/API/Window/orientation, compat.spec.whatwg.org/#dom-window-orientation) that some mobile browsers choose to support for unknown reasons. Same browsers implement window.screen.orientation (which is defined in desktop browsers too). I can only assume that window.orientation is left there for legacy reasons and should therefore not be used in new applications.Realgar
True, window.orientation is deprecated but window.screen.orientation does not (yet) work on iOS 11.x (returns 'undefined').Traumatize
Then simply use if(window.orientation || window.screen.orientation) {}. Problem solvedBindery
@AliMertCakar I agree, but chrome (and may be others) defines window.screen.orientation in the desktop. Cheers.Dyaus
screen.orientation is also supported on desktop developer.mozilla.org/en-US/docs/Web/API/Screen/…Kreis
To go deeper on @lctus's comment, as of this writing, I don't think answer is usable any more, and should be updated to that effect. On the desktop versions of both Chrome and Firefox, screen.orientation is defined, so this solution will provide false positives for at least those desktop browsers.Jacket
Doesn't work any moreEnscroll
Well my Windows 10's Chrome 103 says that screen.orientation is defined ¯_(ツ)_/¯Duet
It is not working solution anymore. Works also on PC.Poplin
Problem with screen.orientation: you can just use this to check if screen is in portrait mode or not. This is obj value on mobile phones: Screen.orientation.type = 'portrait-primary', but as soon as your rotate your phone to landscape the value changes, so this makes it useless to detect if its mobile browser or not.Eustacia
At the moment the easiest way is still window.orientation. If you read properly it is actually not deprecated. They deprecated it only on desktop browsers. On mobile browsers it still has full support even in the newest browsers!Eustacia
@Eustacia window.orientation is deprecated for all browsers. What you're not getting is that it was intentionally undefined on desktop browsers (and in case of mobile ones, it's deprecated).Abdulabdulla
@yoavbarnea On the other hand, screen.orientation will not work because on new browsers it will never be undefined.Abdulabdulla
@Abdulabdulla you are wrong about deprecation on all browsers. Scroll to the bottom of the page developer.mozilla.org/en-US/docs/Web/API/Window/orientation Even Mobile Chrome Version 114.0.5735.199 has full support for it caniuse.com/?search=window.orientationEustacia
@Eustacia what you are seeing is the compatibility table saying if it works or not, deprecation typically means it works, but it will not work anymore at some point in the future. Both links you provided are saying the same thing. The table you see on MDN has a trash icon on the left (and a big warning at the start of the page) and caniuse specifically says: This feature is deprecated/obsolete and should not be used.Abdulabdulla
This answer is not relevant now I recommend to remove it, because screen.orientation exists in desktop.Tallent
A
167
const isMobile = {
    Android: function() {
        return navigator.userAgent.match(/Android/i);
    },
    BlackBerry: function() {
        return navigator.userAgent.match(/BlackBerry/i);
    },
    iOS: function() {
        return navigator.userAgent.match(/iPhone|iPad|iPod/i);
    },
    Opera: function() {
        return navigator.userAgent.match(/Opera Mini/i);
    },
    Windows: function() {
        return navigator.userAgent.match(/IEMobile/i) || navigator.userAgent.match(/WPDesktop/i);
    },
    any: function() {
        return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
    }
};

How to use

if( isMobile.any() ) alert('Mobile');

To check to see if the user is on a specific mobile device:

if( isMobile.iOS() ) alert('iOS');

Ref: http://www.abeautifulsite.net/blog/2011/11/detecting-mobile-devices-with-javascript

Enhanced version on github : https://github.com/smali-kazmi/detect-mobile-browser

Algebraist answered 11/12, 2012 at 11:20 Comment(10)
Why not make any() a for...in loop of ORed isMobile members?Adipose
@ChristopherW i had created its plugin and modified code as you advisedAlgebraist
@Rob_vH i had put this code into github (github.com/smali-kazmi/detect-mobile-browser) with some advance features; you are open to send suggestions there as wellAlgebraist
This one gets my upvote for content, but I'm trying to figure out how to convert it to John Papa's styling and having some difficulty. Still quite new to AngularJS as a whole (about a month into knowledge of it) and the vm. notation angles the learning curve upward a bit. Any help? -C§ EDIT: I'm trying to unit test it with karma-jasmine is why I ask.Wifeless
@AkarshSatija Does the performance drop from those 5 regex checks actually impact any of your applications? I would be very surprised if it did. Premature optimization can be a waste of time...Calefactory
@Calefactory regex match is an expensive operation and handheld devices are always a little challenge at computing. There's no rationale around against Premature optimizations but they come back and bite very soon at your worsts. Also, why not go for optimization when better options are available?Trigonal
may i suggest any: () => /Mobile/.test(navigator.userAgent)Maggiore
I agree with @oriadam, because of the return type match(): RegExpMatchArray, test(): boolean . So when using TypeScript there will be an error.Shellacking
@Maggiore this will always true: any: () => /Mobile/.test(navigator.userAgent)!!Hexone
instead of (isMobile.Android() || isMobile.BlackBerry()........ how about (this.Android() || this.BlackBerry()......Cryo
J
162

Here is a simple solution from the source of facebook's slingshot

const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
if (isMobile) {
  /* your code here */
}
Jadwiga answered 8/4, 2015 at 8:11 Comment(6)
Nice. Very useful in certain situationsRosebay
Useful for the case of detecting a device where a mobile app could be installed. You don't care about the browser, per se. Just the device / OS.Sadducee
Neat! Still works in 2021, albeit I'd add a let isMobile= nowBalsaminaceous
Works on Windows Phone / webOS / Blackberry ?Comorin
What about android TVs.Nearby
I'd add a const isMobile = (; @BalsaminaceousPoetess
C
64

Came here looking for a simple, clean way to detect "touch screens devices", which I class as mobile and tablets. Did not find a clean choice in the current answers but did work out the following which may also help someone.

var touchDevice = ('ontouchstart' in document.documentElement);

Edit: To support desktops with a touch screen and mobiles at the same time you can use the following:

var touchDevice = (navigator.maxTouchPoints || 'ontouchstart' in document.documentElement);
Clubbable answered 17/4, 2016 at 5:58 Comment(8)
What if desktop's monitor supports touch?Arruda
@HappyCoder I believe it is up to the OS to tell the browser when the touch screen on a desktop is active. So, yes this check should still be valid.Clubbable
(+1), however, my desktop I'm using now has a touchScreen, and it isn't always consistent for touchstart|end|etc.Alansen
Bootstrap datepicker uses the following: if ( window.navigator.msMaxTouchPoints || 'ontouchstart' in document) { this.input.blur(); }Odelet
@J.T.Taylor It looks like Microsoft is recommending navigator.maxTouchPoints (no ms prefix). There is also an MDN article to check.Clubbable
what if use hammer.. for me return true... ('ontouchstart' in document.documentElement)Jobe
take care maxTouchPoints is broken, I have no touchscreen and in chrome it returns 256. This fixed the issue for me: navigator.maxTouchPoints & 0xFF #55833826Eustacia
This should be the accepted answer. Simple and Reliable if you design is concerning the touch input and mouse input behaviour.Smokechaser
I
58

According to MDN's article on Browser detection using the user agent, it is encouraged to avoid this approach if possible and suggest other avenues such as feature detection.

However, if one must use the user agent as a means to detect if the device is mobile, they suggest:

In summary, we recommend looking for the string “Mobi” anywhere in the User Agent to detect a mobile device.

Therefore, this one-liner will suffice:

const isMobileDevice = window.navigator.userAgent.toLowerCase().includes("mobi");

[UPDATE]:

As @zenw0lf suggests in the comments, using a Regular Expression would be better:

const isMobileDevice = /Mobi/i.test(window.navigator.userAgent)

Irreversible answered 14/8, 2017 at 1:53 Comment(5)
.includes not sopport by IE-11Fuld
@PashaOleynik a polyfill can fix thatSpermaceti
Nexus 7 tablet with Android does not have Mobile in the user agent stringDonetsk
@AlexSorokoletov Also for the MDN article If the device is large enough that it's not marked with “Mobi”, you should serve your desktop site (which, as a best practice, should support touch input anyway, as more desktop machines are appearing with touchscreens).Irreversible
I think this is would work anywhere without polyfills: const isMobile = /Mobi/.test(window.navigator.userAgent)Glarum
B
44

As many have stated, relying on the moving target of the user agent data is problematic. The same can be said for counting on screen size.

My approach is borrowed from a CSS technique to determine if the interface is touch:

Using only javascript (support by all modern browsers), a media query match can easily infer whether the device is mobile.

function isMobile() {
    var match = window.matchMedia || window.msMatchMedia;
    if(match) {
        var mq = match("(pointer:coarse)");
        return mq.matches;
    }
    return false;
}
Basin answered 9/8, 2018 at 18:57 Comment(8)
What about laptops with touch enabled displays?Spermaceti
I would check for !matchMedia("(any-pointer:fine)").matches myself. ("No mouse plugged in", rather than "has a touch screen".Shebeen
This works whereas my last script would get tricked by people using the browser's zoom feature (e.g. a guy I was talking with on a 13" screen with 4K who dropped to 1080p and still had to use zoom). Worked on my iPhone (Safari/Firefox) and Android devices (Waterfox/Chrome/"Browser"). Definitely much more reliable than all the higher up-voted answers.Panhellenic
does not detect FireFox fennec on an Android for which I supplemented with navigator.userAgent.toLowerCase().indexOf('fennec') > -1 (perhaps not the best supplement..)Andersonandert
Additionnally you can test the hover property: for smartphones and touchscreens @media (hover: none) and (pointer: coarse)Morelli
how widely "supported" is checking any-pointer and hover with MQs? i know MDN says theyre candidate recommendations, soooTorsi
According to this: caniuse.com/matchmedia, it's pretty widely support for all modern browsers. The only browsers to be concerned about are mobile browsers since that function will return false for all other browsers whether they support matchMedia or not. So based on caniuse.com, only 0.03% of global users are not supported.Basin
Responses 'false' on a laptop with touchscreen. Hooray!Abbatial
P
20

There's no perfect solution for detecting whether JS code is executed on a mobile browser, but the following two options should work in most cases.

Option 1 : browser sniffing

!function(a){var b=/iPhone/i,c=/iPod/i,d=/iPad/i,e=/(?=.*\bAndroid\b)(?=.*\bMobile\b)/i,f=/Android/i,g=/(?=.*\bAndroid\b)(?=.*\bSD4930UR\b)/i,h=/(?=.*\bAndroid\b)(?=.*\b(?:KFOT|KFTT|KFJWI|KFJWA|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|KFARWI|KFASWI|KFSAWI|KFSAWA)\b)/i,i=/IEMobile/i,j=/(?=.*\bWindows\b)(?=.*\bARM\b)/i,k=/BlackBerry/i,l=/BB10/i,m=/Opera Mini/i,n=/(CriOS|Chrome)(?=.*\bMobile\b)/i,o=/(?=.*\bFirefox\b)(?=.*\bMobile\b)/i,p=new RegExp("(?:Nexus 7|BNTV250|Kindle Fire|Silk|GT-P1000)","i"),q=function(a,b){return a.test(b)},r=function(a){var r=a||navigator.userAgent,s=r.split("[FBAN");return"undefined"!=typeof s[1]&&(r=s[0]),s=r.split("Twitter"),"undefined"!=typeof s[1]&&(r=s[0]),this.apple={phone:q(b,r),ipod:q(c,r),tablet:!q(b,r)&&q(d,r),device:q(b,r)||q(c,r)||q(d,r)},this.amazon={phone:q(g,r),tablet:!q(g,r)&&q(h,r),device:q(g,r)||q(h,r)},this.android={phone:q(g,r)||q(e,r),tablet:!q(g,r)&&!q(e,r)&&(q(h,r)||q(f,r)),device:q(g,r)||q(h,r)||q(e,r)||q(f,r)},this.windows={phone:q(i,r),tablet:q(j,r),device:q(i,r)||q(j,r)},this.other={blackberry:q(k,r),blackberry10:q(l,r),opera:q(m,r),firefox:q(o,r),chrome:q(n,r),device:q(k,r)||q(l,r)||q(m,r)||q(o,r)||q(n,r)},this.seven_inch=q(p,r),this.any=this.apple.device||this.android.device||this.windows.device||this.other.device||this.seven_inch,this.phone=this.apple.phone||this.android.phone||this.windows.phone,this.tablet=this.apple.tablet||this.android.tablet||this.windows.tablet,"undefined"==typeof window?this:void 0},s=function(){var a=new r;return a.Class=r,a};"undefined"!=typeof module&&module.exports&&"undefined"==typeof window?module.exports=r:"undefined"!=typeof module&&module.exports&&"undefined"!=typeof window?module.exports=s():"function"==typeof define&&define.amd?define("isMobile",[],a.isMobile=s()):a.isMobile=s()}(this);

alert(isMobile.any ? 'Mobile' : 'Not mobile');

This particular browser sniffing code is that of a library called isMobile.


Option 2 : window.orientation

Test if window.orientation is defined :

var isMobile = window.orientation > -1;
alert(isMobile ? 'Mobile' : 'Not mobile');

Note

Not all touchscreen devices are mobile and vice versa. So, if you want to implement something specifically for touchscreen, you shouldn't test if your browser is run on a mobile device but rather whether the devices has touchscreen support :

var hasTouchscreen = 'ontouchstart' in window;
alert(hasTouchscreen ? 'has touchscreen' : 'doesn\'t have touchscreen');
Permutation answered 12/3, 2016 at 2:31 Comment(6)
Orientation approach is really nice! ))Spermaceti
I like your window.orientation solution, but the docs say it's deprecated! developer.mozilla.org/en-US/docs/Web/API/Window/orientationLobel
Orientation approach is NOT nice because Windows 8 and higher can change orientation.Trangtranquada
Windows 8 and newer are focused on adding support for mobiles but also hybrids (laptops that can convert to large pads) which is why orientation fails as a detection method even if moz wasn't referring to it as deprecated.Hive
It's from Win 7 with Graphical Software installed can change orientation but ask yourself a question, who can on Desktop / Laptop use a another screen orientation like Portrait instead of Landscape and use i for even more than 1 minute. No one !!! Changing orientation on Desktop means you'll start reading characters on your screen from bottom to top.Cache
See this other answer. .orientation is no longer a solution to this problem.Trihedron
L
16

Here is a userAgent solution that is more efficent than match...

function _isMobile(){
    // if we want a more complete list use this: http://detectmobilebrowsers.com/
    // str.test() is more efficent than str.match()
    // remember str.test is case sensitive
    var isMobile = (/iphone|ipod|android|ie|blackberry|fennec/).test
         (navigator.userAgent.toLowerCase());
    return isMobile;
}
Likker answered 4/12, 2012 at 16:19 Comment(1)
the test method is not case sensitive, but your regex is. you could just flag for case insensitive regex with an "i" at the end and do /iphone|etc/i.test(navigator.userAgent)Stadler
L
13

Feature detection is much better than trying to figure out which device you are on and very hard to keep up with new devices coming out all the time, a library like Modernizr lets you know if a particular feature is available or not.

Lyndialyndon answered 5/4, 2013 at 0:48 Comment(3)
You've answered another question than what was asked. Rather than "how can I detect mobile?", you've answered "how can I detect certain features?". Not all device detection is for feature detection. What if we were looking to get statistics about devices? Then no, "feature detection" is not "much better than [figuring out device]".Salyers
This is not the answer, but it deserves more than just a comment. The question is: why do you want to detect a browser and then you will probably want to know it because of the (lack of) touch only. Responsive webdesign suffices in most if not all cases.Chevrotain
What if the feature I want to detect is how powerful the device CPU is? I need to lower quality on mobile phones...Doorbell
D
12

To add an extra layer of control I use the HTML5 storage to detect if it is using mobile storage or desktop storage. If the browser does not support storage I have an array of mobile browser names and I compare the user agent with the browsers in the array.

It is pretty simple. Here is the function:

// Used to detect whether the users browser is an mobile browser
function isMobile() {
    ///<summary>Detecting whether the browser is a mobile browser or desktop browser</summary>
    ///<returns>A boolean value indicating whether the browser is a mobile browser or not</returns>

    if (sessionStorage.desktop) // desktop storage 
        return false;
    else if (localStorage.mobile) // mobile storage
        return true;

    // alternative
    var mobile = ['iphone','ipad','android','blackberry','nokia','opera mini','windows mobile','windows phone','iemobile']; 
    for (var i in mobile) if (navigator.userAgent.toLowerCase().indexOf(mobile[i].toLowerCase()) > 0) return true;

    // nothing found.. assume desktop
    return false;
}
Discriminating answered 18/4, 2013 at 10:17 Comment(2)
I haven't tested on mobile yet, but sessionStorage.desktop doesn't exist in either Safari, Chrome, or Firefox (all newest versions at time of post). You get an up-vote though, since your solution goes in a better direction than others. But don't forget to use var mobile = instead of mobile =.Truckle
Also a good idea not to use indexOf with older browsers still being around which don't support that method, or to use a polyfill. It's not necessary to use toLowerCase on a list of lowercase values, nor is it necessary to do so if you're running /ipad|iphone|etc/i.test(navigator.userAgent) instead of the slow loop you have up there.Discombobulate
C
11

A really good way of detecting mobile or tablet devices is by looking if the browser can create a touch event.

Plain JavaScript Code:

function isMobile() {
   try{ document.createEvent("TouchEvent"); return true; }
   catch(e){ return false; }
}

if (isMobile()) {
   # do whatever you wanna do!
}

This worked for me really well, but there may be a problem with laptop devices which include a touchscreen display.

I am not sure if a touchscreen Laptop will get detected as a mobile device because I haven't tested it yet.

Cornflower answered 22/3, 2018 at 10:12 Comment(6)
Touch screen laptops will be detected as mobile device. As well as touch screen monitors for desktops. Believe it or not, you will also run into issue if you are using touchscreen device to RDP into another device that is does not have a touch screen.Aldehyde
@Aldehyde i guess this will not be the right way for detecting mobile devices then.Cornflower
Unfortunately, no. But, it might still be a viable option for a very limited use case.Aldehyde
never write code, that is based on an exception, that will be throwen for sure in any case...Oribelle
@Sivic it only gets thrown when a TouchEvent does not exists and the code above catches it and returns false. This is not the case on Mobile or Tablet or other Touch Screen devices.Cornflower
How about using this with a check on screen size? Considering Bootstrap switches to mobile view below 768px?Vagrancy
L
10

How about something like this?

if(
    (screen.width <= 640) || 
    (window.matchMedia && 
     window.matchMedia('only screen and (max-width: 640px)').matches
    )
  ){
   // Do the mobile thing
}
Loving answered 24/4, 2015 at 2:34 Comment(4)
Why not just use screen.width instead? It seems to me that's more reliable than window.matchMedia.Permutation
Good point John, I can't recall exactly what I was thinking at the time, it seems unlikely (looking at it now) that the second clause would return true if the first is false. There must have been some reason I added it though.Loving
Most decent programmers feel ashamed when they see code they wrote themselves a year earlier. Those who don't just haven't grown as programmers ;-)Permutation
Window resolution has nothing to do with whether a browser is on a mobile device or not. For example, lots of desktop browsers run in non-full-screen windows. If you present a UI designed for handheld screens to those browsers, their users are going to have a frustrating experience.Grodno
B
10

Feature Detection

const isMobile = localStorage.mobile || window.navigator.maxTouchPoints > 1;

WORKS IN CHROME + SAFARI as of 2022-02-07 :: combining feature detections and trying everything in this thread and other sites. The localStorage.mobile works in Chrome mobile; the latter works in Safari mobile. Does not trigger desktop browsers with or w/o the dev-tools open and/or on a mobile simulator. As of writing this, it triggers a real mobile browser but not desktops.

Please consider

I've also tested this on a Lenovo X1 Yoga (keyboard or tablet-mode) on Win10

  1. localStorage.mobile is undefined no matter what
  2. When the laptop is in keyboard mode:
    window.navigator.maxTouchPoints is 1
    → isMobile is false
  3. When the keyboard is flipped back and the laptop is in tablet-mode:
    window.navigator.maxTouchPoints is 10
    → isMobile is true
Bode answered 8/2, 2022 at 7:38 Comment(4)
maxTouchPoints - what if laptop has a touch screen?Dye
@Dye that was a very good question---thanks. I tested it for us, as I have a Lenovo X1 Yoga available with Win10. 1) localStorage.mobile is undefined no matter what. 2) When the laptop is in keyboard mode, window.navigator.maxTouchPoints is 1; so isMobile was false. 3) When the keyboard is flipped back and the laptop is in tablet mode, window.navigator.maxTouchPoints is 10; so isMobile was true. Now the subjective question: Do we consider a tablet or laptop in tablet-mode as mobile? 🤔Bode
Great work, works on Firefox for Android too.Counterforce
localstorage.mobile is something you have to define, this answer code is incomplete.Zacatecas
T
9

Depends on the use case. All mobile devices require a battery. If what you're after is compute power without draining the battery use the Battery Status API:

navigator.getBattery().then(battery => {
  battery.charging ? 'charging' : 'not charging';
});

If what you're looking for is presentational use matchMedia, which returns a Boolean value:

if (window.matchMedia("(min-width: 400px)").matches) {
  /* the viewport is at least 400 pixels wide */
} else {
  /* the viewport is less than 400 pixels wide */
}

Or combine them for an even better user experience on tablet devices.

Trellas answered 22/11, 2018 at 12:22 Comment(4)
Note that the Battery Status API is being removed from browsers.Shebeen
checking battery, thats smartTorsi
Clever, what happens if computer is using ups?Rajiv
While laptops are "mobile", they are usually treated as desktop. So battery check is not enough.Wouldbe
B
8

don't use this method as window.orientation is now deprecated!!!

function isMobile() {
  return (typeof window.orientation !== "undefined") || (navigator.userAgent.indexOf('IEMobile') !== -1);
};
Bebop answered 1/5, 2018 at 21:40 Comment(1)
window.orientation is deprecated. This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.Gorgonian
O
7

Once the element gains focus, you immediately blur it. Bootstrap-datepicker, which is a very popular and well-maintained component with almost 10,000 stars in GitHub, uses this approach:

if (window.navigator.maxTouchPoints || 'ontouchstart' in document) {
    this.input.blur();
}

https://github.com/uxsolutions/bootstrap-datepicker

Thanks to Tigger for assistance.

Odelet answered 15/7, 2017 at 0:37 Comment(0)
A
6

Here is my re-thought solution for the problem. Still not perfect. The only true solution would be if the device manufacturers start to take seriously the "Mobile" and "Tablet" user-agent strings.

window.onload = userAgentDetect;
function userAgentDetect() {
  if(window.navigator.userAgent.match(/Mobile/i)
  || window.navigator.userAgent.match(/iPhone/i)
  || window.navigator.userAgent.match(/iPod/i)
  || window.navigator.userAgent.match(/IEMobile/i)
  || window.navigator.userAgent.match(/Windows Phone/i)
  || window.navigator.userAgent.match(/Android/i)
  || window.navigator.userAgent.match(/BlackBerry/i)
  || window.navigator.userAgent.match(/webOS/i)) {
    document.body.className += ' mobile';
    alert('True - Mobile - ' + navigator.userAgent);
  } else {
    alert('False - Mobile - ' + navigator.userAgent);
  }
  if(window.navigator.userAgent.match(/Tablet/i)
  || window.navigator.userAgent.match(/iPad/i)
  || window.navigator.userAgent.match(/Nexus 7/i)
  || window.navigator.userAgent.match(/Nexus 10/i)
  || window.navigator.userAgent.match(/KFAPWI/i)) {
    document.body.className -= ' mobile';
    document.body.className += ' tablet';
    alert('True - Tablet - ' + navigator.userAgent);
  } else {
    alert('False - Tablet - ' + navigator.userAgent);
  }
}

What happens when the Nexus 7 tablet only have the Android UA string? First, the Mobile become true, than later on the Tablet also become true, but Tablet will delete the Mobile UA string from the body tag.

CSS:

body.tablet { background-color: green; }
body.mobile { background-color: red; }

alert lines added for development. Chrome console can emulate many handheld devices. Test there.

EDIT:

Just don't use this, use feature detection instead. There are so many devices and brands out there that targeting a brand NEVER will be the right solution.

Alcock answered 6/8, 2015 at 19:21 Comment(1)
"Just don't use this" ? You can always delete your answer. Also, all those .match( ... hm. RegExp and .test() is a simpler variant.Boat
P
5

UserAgent is not 100% reliable.

window.navigator.maxTouchPoints > 1;

This is just enough! It excludes phone emulators in browser dev console. That was important for me.

Principium answered 16/12, 2022 at 8:31 Comment(1)
This won't work users with touch enabled display like chromebook.Lu
V
4

Here is a less obfuscated version of the answer by Michael Zaporozhets. It also uses a check to build the regular expressions only on the first call. See this answer for the technique used to build the string from an array of regular expressions.

var gRE = null;
var gRE4 = null;

function PlatformIsMobile()
{
    var e;
    
    if ( gRE == null )
    {
        e =
            [
                /(android|bb\d+|meego).+mobile|avantgo/,
                /bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile/,
                /ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox/,
                /netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker/,
                /pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone/,
                /wap|windows ce|xda|xiino|android|ipad|playbook|silk/
            ];
        
        gRE = new RegExp(
            e.map( function( r ) { return r.source } ).join( "|" ), "i"
        );
    }
    
    if ( gRE4 == null )
    {
        e =
            [
                /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa/,
                /abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)/,
                /aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan/,
                /be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)/,
                /c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw/,
                /da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)/,
                /el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)/,
                /g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)/,
                /haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)/,
                /i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris/,
                /ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)/,
                /le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx/,
                /m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)/,
                /mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]/,
                /n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph/,
                /o2im|op(ti|wv)|oran|owg1/,
                /p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g/,
                /qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek/,
                /r380|r600|raks|rim9|ro(ve|zo)/,
                /s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)/,
                /sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)/,
                /t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo/,
                /to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst/,
                /v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)/,
                /w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/
            ];
        
        gRE4 = new RegExp(
            e.map( function( r ) { return r.source } ).join( "|" ), "i"
        );
    }
    
    var key = navigator.userAgent || navigator.vendor || window.opera;
    
    return gRE.test( key ) ||
           gRE4.test( key.substr( 0, 4 ) );
}
Vin answered 21/3, 2021 at 3:38 Comment(0)
C
3

I advise you check out http://wurfl.io/

In a nutshell, if you import a tiny JS file:

<script type='text/javascript' src="//wurfl.io/wurfl.js"></script>

you will be left with a JSON object that looks like:

{
 "complete_device_name":"Google Nexus 7",
 "is_mobile":true,
 "form_factor":"Tablet"
}

(that's assuming you are using a Nexus 7, of course) and you will be able to do things like:

if(WURFL.form_factor == "Tablet"){
    //dostuff();
}

This is what you are looking for.

Disclaimer: I work for the company that offers this free service. Thanks.

Capsule answered 5/5, 2016 at 2:34 Comment(4)
And howcome this does not recognize safari on iphone ?Propagable
Can you expand on what browser you are using (exact UA string would be perfect), what data you are getting and what you are expecting?Capsule
I too tried wurfl, I am on a iPhone 5C running IOS 11.2. Its not recognising Safari as a mobile browser. I'm expecting to use "is_mobile" : true and then "form_factor": Smartphone and its not returning either.Wayworn
I had to turn to the Mobile Data gurus in the company and they tell me that OS 11.2 doesn't run on the 5C. Lowest device is the 5S. So something isn't right in what you wrote. Feel free to contact ScientiaMobile offline to verify where the disconnect might be. ThanksCapsule
A
3

Note that Most newer-gen mobile devices now have resolutions greater than 600x400. ie, an iPhone 6....

Proof of test: ran the most upvoted and most recent posts here, with an optional check once run like so:

(function(a){
    window.isMobile = (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))
})(navigator.userAgent||navigator.vendor||window.opera);

alert("This browser was found to be a % browser.", window.isMobile ? 'mobile' : 'desktop');

Somehow, the following results were returned on the following Browser Apps. Specs: iPhone 6S, iOS 10.3.1.

Safari (latest): Detected it as a mobile.

Chrome (latest): Did not detect it as a mobile.

SO, i then tested the suggestion from Lanti (https://mcmap.net/q/42141/-detecting-a-mobile-browser), and it did return the proper results (mobile for all iOS devices, and desktop for my Mac). Therefore, i proceeded to edit it a little since it would fire twice (for both mobile and Tablet). I then noticed when testing on an iPad, that it also returned as a mobile, which makes sense, since the Parameters that Lanti uses check the OS more than anything. Therefore, i simply moved the tablet IF statement inside the mobile check, which would return mobile is the Tablet check was negative, and tablet otherwise. I then added the else clause for the mobile check to return as desktop/laptop, since both qualify, but then noticed that the browser detects CPU and OS brand. So i added what is returned in there as part of else if statement instead. To cap it, I added a cautionary else statement in case nothing was detected. See bellow, will update with a test on a Windows 10 PC soon.

Oh, and i also added a 'debugMode' variable, to easily switch between debug and normal compiling.

Dislaimer: Full credit to Lanti, also that this was not tested on Windows Tablets... which might return desktop/laptop, since the OS is pure Windows. Will check once I find a friend who uses one.

function userAgentDetect() {
    let debugMode = true;
    if(window.navigator.userAgent.match(/Mobile/i)
        || window.navigator.userAgent.match(/iPhone/i)
        || window.navigator.userAgent.match(/iPod/i)
        || window.navigator.userAgent.match(/IEMobile/i)
        || window.navigator.userAgent.match(/Windows Phone/i)
        || window.navigator.userAgent.match(/Android/i)
        || window.navigator.userAgent.match(/BlackBerry/i)
        || window.navigator.userAgent.match(/webOS/i)) {
        if (window.navigator.userAgent.match(/Tablet/i)
            || window.navigator.userAgent.match(/iPad/i)
            || window.navigator.userAgent.match(/Nexus 7/i)
            || window.navigator.userAgent.match(/Nexus 10/i)
            || window.navigator.userAgent.match(/KFAPWI/i)) {
            window.deviceTypeVar = 'tablet';
            if (debugMode === true) {
                alert('Device is a tablet - ' + navigator.userAgent);
            }
        } else {
            if (debugMode === true) {
                alert('Device is a smartphone - ' + navigator.userAgent);
            };
            window.deviceTypeVar = 'smartphone';
        }
    } else if (window.navigator.userAgent.match(/Intel Mac/i)) {
        if (debugMode === true) {
            alert('Device is a desktop or laptop- ' + navigator.userAgent);
        }
        window.deviceTypeVar = 'desktop_or_laptop';
    } else if (window.navigator.userAgent.match(/Nexus 7/i)
        || window.navigator.userAgent.match(/Nexus 10/i)
        || window.navigator.userAgent.match(/KFAPWI/i)) {
        window.deviceTypeVar = 'tablet';
        if (debugMode === true) {
            alert('Device is a tablet - ' + navigator.userAgent);
        }
    } else {
        if (debugMode === true) {
            alert('Device is unknown- ' + navigator.userAgent);
        }
        window.deviceTypeVar = 'Unknown';
    }
}
Anyhow answered 11/5, 2017 at 19:56 Comment(0)
F
3

This is just an es6 port of the accepted answer that I'm using in my project. Note that this also includes tablets.

export const isMobile = () => {
  const vendor = navigator.userAgent || navigator.vendor || window.opera;

  return !!(
    /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(
      vendor
    ) ||
    /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55\/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene|gf-5|g-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk\/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-/i.test(
      vendor.substr(0, 4)
    )
  );
};
Fagaceous answered 4/1, 2018 at 16:27 Comment(0)
B
3

I have faced some scenarios where above answers dint work for me. So i came up with this. Might be helpful to someone.

if(/iPhone|iPad|iPod|Android|webOS|BlackBerry|Windows Phone/i.test(navigator.userAgent)
 || screen.availWidth < 480){
//code for mobile
}

It depends on your use case. If you focus on screen use screen.availWidth, or you can use document.body.clientWidth if you want to render based on document.

Bolan answered 25/6, 2019 at 6:27 Comment(0)
V
3

This is what I use. I know userAgent sniffing is frowned upon, but my need happens to be one of the exclusions!

<script>
var brow = navigator.userAgent;
    if (/mobi/i.test(brow)) {
        alert('Mobile Browser');
        // Do something for mobile
    } else {
        alert('Not on Mobile');
        // Do something for non mobile
    }
</script>
Ventilator answered 7/5, 2020 at 13:3 Comment(0)
S
2

The best must be :

var isMobile = (/Mobile/i.test(navigator.userAgent));

But like like Yoav Barnea says...

// Seem legit
var isMobile = ('DeviceOrientationEvent' in window || 'orientation' in window);
// But with my Chrome on windows, DeviceOrientationEvent == fct()
if (/Windows NT|Macintosh|Mac OS X|Linux/i.test(navigator.userAgent)) isMobile = false;
// My android have "linux" too
if (/Mobile/i.test(navigator.userAgent)) isMobile = true;

After this 3 tests, i hope var isMobile is... ok

Skolnik answered 30/5, 2013 at 12:34 Comment(4)
> Firefox mobile on android doesn't seem to have "'orientation' in window"Skolnik
Sorry.. ok for me it work well like that now. "if (Modernizr.touch) /* ... */ " and go on...Skolnik
Just wondering how Modernizr.touch would work when on a touchscreen desktop device.Berthoud
To make it more elegant you should make all te code in just one if-else if-else if block.Trangtranquada
S
2

Here is he full function

function isMobile(){
    return (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino|android|ipad|playbook|silk/i.test(navigator.userAgent||navigator.vendor||window.opera)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test((navigator.userAgent||navigator.vendor||window.opera).substr(0,4)))
}

jQuery.noConflict();
jQuery(document).ready(function(){
    if(isMobile()) alert("Mobile"); else alert("Not Mobile");
});
Schifra answered 1/6, 2013 at 0:25 Comment(3)
.substr(0,4) returns first 4 letters. How does it detect "android.+mobile"?Hexavalent
@Hexavalent there are actually two regexes in the answer (both on the same line) - the first one checks against the entire UA string, and looks for android, mobile etc, while the second one only checks against the first 4 characters of the UA.Clinkstone
It worked! thanks so much.Vernal
O
2

Here's an ECMAScript 6 solution (TypeScript ready)

public isMobile(): boolean {
  let check = false;
  ((a => {
      if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true;
      }))(navigator.userAgent || navigator.vendor);
  return check;
 }
Odaniel answered 23/2, 2017 at 8:18 Comment(1)
why not just return the if condition instead of having this whole check variable?Francesco
D
2

Using Regex (from detectmobilebrowsers.com):

/* eslint-disable */
export const IS_MOBILE = (function (a) {
  return (
    /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i
      .test(
        a.substr(0,4)
      )
  )
  // @ts-ignore
})(navigator.userAgent || navigator.vendor || window.opera)
/* eslint-enable */
December answered 4/10, 2019 at 12:17 Comment(1)
if a user is using Chrome in Desktop mode, it fill fail. Combined with media query would work alrightRetool
I
2

Ah yes, the age old question...

It really depends on what you want to do in response to the knowledge.

1. Do you want to change UI so it fits nicely on different screen sizes?

Use media queries.

2. Do you want to show/hide things or change functionality based on mouse vs touch?

This answer above will do however there could be cases where a user has both and switches around. In that scenario you can toggle some JS variable and/or add a class to the document body when you detect mouse or touch events

  window.addEventListener("mousemove", function () {
    isTouch = false;
    document.body.classList.add("canHover");
  });
  window.addEventListener("touchstart", function () {
    isTouch = true;
    document.body.classList.remove("canHover");
  });
body.canHover #aButtonOrSomething:hover {
  //css attributes
}
  document
    .getElementById("aButtonOrSomething")
    .addEventListener("mouseover", showTooltip);
  document
    .getElementById("aButtonOrSomething")
    .addEventListener("click", function () {
      if (isTouch) showTooltip();
    });

3. Do you want to do something specific knowing exactly what device they have?

Use the accepted answer.

Intercalation answered 18/3, 2021 at 18:2 Comment(0)
S
2
  function isMobile() {
    if ('maxTouchPoints' in navigator) return navigator.maxTouchPoints > 0;

    const mQ = matchMedia?.('(pointer:coarse)');
    if (mQ?.media === '(pointer:coarse)') return !!mQ.matches;
    
    if ('orientation' in window) return true;
    
    return /\b(BlackBerry|webOS|iPhone|IEMobile)\b/i.test(navigator.userAgent) ||
      /\b(Android|Windows Phone|iPad|iPod)\b/i.test(navigator.userAgent);
  }

navigator.userAgent sniffing is not recommended since it's not reliable and heavily varies. As you can see here: https://developers.whatismybrowser.com/useragents/explore/ the navigator.userAgent strings can vary greatly between versions of the same browser.

This MDN article can back this statement: https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent#avoiding_user_agent_detection.

The answer above is a refactor of the suggested solution for mobile detection from the noted MDN article. It relies on feature checks first and then fallbacks as a last resort to navigator.userAgent sniffing.

Happy coding! <3

P.S. You can find isMobule function together with isIOS, isSafari and isIOSSafari as a part of my small ESM library https://github.com/stamat/book-of-spells in form of a NPM/YARN package book-of-spells. It's a library of my JS snippets, please do contribute if you see fit and feel free to use any part of it!

Spurling answered 15/9, 2022 at 13:2 Comment(4)
Is not working for me, how do you use it?Howard
@Howard hey I think I forgt to add function in front of the the function name 😂 Anyway just call the function isMobile(); and it should return true if mobile device detected or false if not.Spurling
This doesn't work if you have a laptop with a touch screen :(Gusher
@Gusher hey, can yoy tell me which laptop do you have and what browser are you using? I wanna look this up! Thanks!Spurling
B
2

I think this is the real protecting soltution.

Testet on Chrome & Firefox, Mobile and on Desktop.

var ___isMobileDevice;
const isMobileDeviceCheck = () => {
    const mobileOsRegExp = "(Android|webOS|iPhone|iPod)";
    if(screen.width < 500 || navigator.userAgent.match('/'+mobileOsRegExp+'/i')) {
        ___isMobileDevice = true;
    }
    if (___isMobileDevice) {
        if (typeof window.orientation === "undefined") {
            ___isMobileDevice = false; 
        }
    }
    if (typeof navigator.userAgentData != "undefined" && !navigator.userAgentData.mobile) {
        ___isMobileDevice = false; 
    }
    if ( typeof window.orientation !== "undefined" && ___isMobileDevice ) {
        if (window.navigator.maxTouchPoints > 1 && (navigator.userAgentData.mobile || localStorage.mobile || 'ontouchstart' in document)) {
            // mobile device found
            console.log('Is mobile device!'); 
        }
    }
}
window.onresize = () => {
    isMobileDeviceCheck();
}
isMobileDeviceCheck();

PS: A Useragent switcher as a browser extension cannot fool you with this code.

Brockington answered 21/9, 2022 at 19:5 Comment(4)
I think you don't need window.navigator.maxTouchPoints > 1 twice :)Banda
Oops, you're right, thanks ^^, I think I missed that with the developmentBrockington
Well, shouldn't you merge your regexes for performance's sake ? Also, I don't understand why you set ___isMobileDevice = ''; in last conditionKarynkaryo
You are right, the Code is updated, my code was a quick solution.Brockington
S
2

By mutually-exclusive feature-detection

const hasCoarsePointer = () => window.matchMedia("(pointer: coarse)").matches
const hasMobileWidth = (maxWidth = 639) =>
  window.matchMedia(`(max-width: ${maxWidth}px)`).matches
const hasMultipleTouchPoints = () => navigator.maxTouchPoints > 1
const hasTouchEvents = () => "ontouchstart" in document.documentElement

export const isMobile = ({ maxWidth } = {}) => {
  return (
    hasCoarsePointer() &&
    hasMultipleTouchPoints() &&
    hasMobileWidth() &&
    hasTouchEvents()
  )
}

joined

export const isMobile = ({ maxWidth = 639 } = {}) => {
  return (
    window.matchMedia("(pointer: coarse)").matches &&
    navigator.maxTouchPoints > 1 &&
    window.matchMedia(`(max-width: ${maxWidth}px)`).matches &&
    "ontouchstart" in document.documentElement
  )
}

*May 5, 2023: window.matchMedia is currently a W3C Working Draft, maxTouchPoints and ontouchstart are in a W3C Editor's Draft. Use with caution.

Ss answered 5/5, 2023 at 18:15 Comment(0)
B
1

what about using "window.screen.width" ?

if (window.screen.width < 800) {
// do something
}

or

if($(window).width() < 800) {
//do something
}

I guess this is the best way because there is a new mobile device every day !

(although I think it's not that supported in old browsers, but give it a try :) )

Ban answered 25/5, 2016 at 7:18 Comment(3)
What is about landscape?Baillargeon
This is not very useful for certain scenarios. If the desktop browser is resized it maybe detected incorrectly as a mobile browserChorale
A PC is essentially different from mobile devices on usability, horrable answer!!Trangtranquada
S
1

return 'ontouchstart' in window && window.screen.availWidth < 768

How about this, it expands on answer above but also checks the screen size

Skeens answered 30/4, 2018 at 23:20 Comment(0)
A
1

This is how you can find out, which device is user using.

if (/ipad|tablet/i.test(navigator.userAgent)) {
    console.log("it's a Ipad"); // your code here
}
else if (/mobile/i.test(navigator.userAgent)) {
     console.log("it's a Mobile");
} else {
     console.log("it's a Desktop");
}
Alum answered 30/5, 2022 at 19:39 Comment(1)
So, checking for other keywords (iPhone, Android, ...) is no longer necessary as suggested in stackoverflow.com/a/44663015 to detect mobile devices?Humphries
H
0

This could also be a solution.

var isMobile = false; //initiate as false

  // device detection
  if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) 
  || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0,4))) isMobile = true;

  console.log('Mobile device:'+isMobile);

  var doc_h = $(document).height(); // returns height of HTML document
  var doc_w = $(document).width(); // returns width of HTML document
  console.log('Height: '+doc_h);
  console.log('width: '+doc_w);

  var iPadVertical = window.matchMedia("(width: 768px) and (height: 1024px) and (orientation: portrait)");
  var iPadHoricontal = window.matchMedia("(width: 1024px) and (height: 767px) and (orientation: landscape)");

  console.log('Height: '+doc_h);
  console.log('width: '+doc_w);

  if (iPadVertical.matches) {
      console.log('Ipad vertical detected');
  }else if (iPadHoricontal.matches){
      console.log('Ipad horicontal detected');
  }else {
      console.log('No Ipad');
  }

If you use both methods, you will get a perfect way to detect different devices.

Hastate answered 18/3, 2016 at 11:45 Comment(0)
L
0
//true / false
function isMobile()
{
   return (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ); 
}

also you can follow this tutorial to detect a specific mobile. Click here.

Larrainelarrie answered 29/4, 2016 at 8:33 Comment(1)
Please add Mobile to your RXMaggiore
S
0

In any case, checking for type of device must be called just ONE TIME: your phone can't surprisingly stay a desktop in a moment :)

So, code for checking by userAgent, suggested here sometime ago, have to be look like that:

(function(a){window.isMobile = (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))})(navigator.userAgent||navigator.vendor||window.opera);

console.info('This is %s device', window.isMoblie ? 'mobile' : 'desktop');
Seitz answered 18/3, 2017 at 14:28 Comment(1)
For my Mi A2, it says that I'm in a desktop...Duet
P
0

There is simple trick to detect whether it is a mobile device or not. Just check if the ontouchstart event exist:

function isMobile()
{
    return "ontouchstart" in window;
}
Propaedeutic answered 25/1, 2018 at 10:20 Comment(1)
Won't work with laptops and dekstops with touchscreen monitors. Also will be an issue with hybrid pc's like Surface. Less of an issue with desktops but there are more touchscreen laptops being sold these days.Aldehyde
F
0

// Function returns true if current device is phone
function isMobile() {

    // regex from http://detectmobilebrowsers.com/mobile
    return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(navigator.userAgent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent)
}

console.log({
    isMobile: isMobile()
});

Fourth answered 9/6, 2020 at 17:35 Comment(0)
H
0

I haven't seen anyone suggested:

window.navigator.connection.type

this only exists on mobile, but not on desktop browsers. It is simpler to just check the existence of that property, i.e. if(window && window.navigator && window.navigator.connection && window.navigator.connection.type) => then it is mobile

NOTE: this is experimental

EDIT (07.2022): The feature is being deemed as a potential tracking exploit, so it is being removed from latest versions. In other words, don't use this!

Hollywood answered 4/2, 2022 at 16:25 Comment(1)
did not worked on chrome as wellKingfisher
D
0

I searched Replit's code ( because it had errors all over the website ) , until I saw:

(function (isTouchDevice) {
      if (!isTouchDevice) return;
      var isTouchClass = 'is-touch-device';
      var docElement = document.documentElement;
      docElement.className = docElement.className ? [docElement.className, isTouchClass].join(' ') : isTouchClass;
    })(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);

so I modified it into something like this:

function isTouchDevice() {
    if (!(("ontouchstart" in window) || (window.DocumentTouch && document instanceof DocumentTouch))) {
        return false
    }
    return true
}

Values from different user agents:

  • Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36: false
  • Mozilla/5.0 (Linux; Android 10; Mi A2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Mobile Safari/537.36: true
Duet answered 13/7, 2022 at 12:49 Comment(0)
T
-1

The touchscreen and orientation solutions won't work on some PCs.

Some laptops have a touchscreen and hopefully more in the future. Also while I can't test it myself, some graphical tablets that work as a screen are a touchscreen capable.

Detecting orientation wouldn't work either. Some PCs like the Microsoft Surface Books have a detachable screen making it work like a tablet, including orientation support. Yet it is still a real PC.

If you have to detect and differentiate between PC and mobile, just read the user agent.
I don't like it either but it remains the best way.

Twombly answered 15/5, 2021 at 19:8 Comment(1)
I can't see any problem with just combining clues, like screen width (not window width) and touch events.Piacular
W
-1

This is the best way ive found nto work in all cases.

const deviceMotionAvailable = Array.isArray(navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/iPhone/i))

Winn answered 11/11, 2022 at 22:27 Comment(2)
That's dreadful and will have many false positives (especially for non-phone-sized Android devices) as well as false negatives (while Apple and Android are almost ubiquitous in the mobile market, they aren't completely ubiquitous).Tyronetyrosinase
lol. you're correct didnt work on Android. How about this approach? /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)Winn
U
-5

I usually find that the simpler approach of checking the visibility of a particular element (say burger icon) that is only visible on mobile views works well and is far safer than relying on a very complicated regex. That would be difficult to test works 100%.

function isHidden(el) {
   return (el.offsetParent === null);
}
Unconnected answered 12/10, 2017 at 12:1 Comment(0)
E
-5
function is_on_mobile(){
    return  screen.width < 535 ;
}
Edda answered 11/10, 2023 at 14:32 Comment(3)
Please add some explanation to your answer such that others can learn from it. This wouldn't work properly for small browser windows on a laptopHyperform
it checks the device's screen, not browser's propertiesEdda
Please add all clarification to your answer by editing itHyperform

© 2022 - 2024 — McMap. All rights reserved.