Is there a way to detect with JavaScript if the website runs inside the iPad's Safari or inside an application WebView?
-
Is this just for iOS devices? – Nicolas S Jun 20 '11 at 20:28
16 Answers
This uses a combination of window.navigator.userAgent
and window.navigator.standalone
. It can distinguish between all four states relating to an iOS web app: safari (browser), standalone (fullscreen), uiwebview, and not iOS.
Demo: http://jsfiddle.net/ThinkingStiff/6qrbn/
var standalone = window.navigator.standalone,
userAgent = window.navigator.userAgent.toLowerCase(),
safari = /safari/.test( userAgent ),
ios = /iphone|ipod|ipad/.test( userAgent );
if( ios ) {
if ( !standalone && safari ) {
//browser
} else if ( standalone && !safari ) {
//standalone
} else if ( !standalone && !safari ) {
//uiwebview
};
} else {
//not iOS
};

- 64,767
- 30
- 146
- 239
-
1chrome has `Safari` in the userAgent. it behaves differently with regard to requiring `webcal://` protocol for .ics files – neaumusic Jun 11 '15 at 22:25
-
@svlada can you provide more information ? What was your device and its iOS version ? – sonlexqt Jun 14 '18 at 10:38
-
1Both Safari and Telegram contains "safari" in user agent, so that won't work – Chris Jan 30 '21 at 21:41
-
Is `typeof window['webkit'] !== 'undefined'` enough to check whether the web page is loaded inside webview ? – oomer Aug 17 '22 at 07:02
-
this answer doesn't work, all in-app browsers just say "browser" on iOS – mesqueeb Dec 19 '22 at 06:35
User Agents
Running in UIWebView
Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/98176
Running in Safari on iPad
Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B176 Safari/7534.48.3
Running in Safari on Mac OS X
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.55.3 (KHTML, like Gecko) Version/5.1.5 Safari/534.55.3
Running in Chrome on Mac OS X
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.151 Safari/535.19
Running in FireFox on Mac OS X
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20100101 Firefox/11.0
Detection Code
var is_uiwebview = /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent);
var is_safari_or_uiwebview = /(iPhone|iPod|iPad).*AppleWebKit/i.test(navigator.userAgent);

- 40,941
- 12
- 84
- 95

- 50,398
- 25
- 166
- 151
-
Really. I don't know why I just looked at both useragents myself in the first place. Thanks for your answer :) – sod Apr 16 '12 at 14:03
-
6Not working on iPhone 5s/iOS 7, because both `UIWebView` and Safari have `Safari` in their user agent – Razor Mar 07 '14 at 10:39
-
@Razor You're right. Testing against `Version` as opposed to `Safari` worked for me in the latest iOS. – unceus Apr 04 '14 at 00:48
-
1@unceus Can you please outline exactly how you mean with `Version`? Do you replace `Safari` with `Version` in the `var is_uiwebview` line? – Henrik Petterson May 28 '16 at 09:46
-
@HenrikPetterson With regard to the user agent strings, comparing the first two user agent strings above (UIWebView, and Safari on iPad) the UIWebView string contains 'version' whereas the ipad one does not. Your goal with modifying the regex is unclear, and it sounds like you might be looking for help writing one. – unceus May 31 '16 at 22:16
-
Would be nice to add WKWebView to this list. In my iPhone X simulator it is: `Mozilla/5.0 (iPhone; CPU iPhone OS 11_2 like Mac OS X) AppleWebKit/604.4.7 (KHTML, like Gecko) Mobile/15C107` – Liron Yahdav Mar 08 '18 at 01:15
-
@neoneye could you please help with related question? https://stackoverflow.com/questions/58344491/request-browser-ismobiledevice-not-working-with-ipadair2-and-ios-13-0-1 – newdeveloper Oct 12 '19 at 05:53
-
@newdeveloper some of the other answers here checks the screen-size and scaling size. HTH. – neoneye Oct 12 '19 at 13:24
-
@neoneye I need to detect in razor syntax and checking screensize may not be proper solution for this. Request.Browser.IsMobileDevice wont detect mobile or iPad anymore as useragent string is not mentioning that anymore. kinda stuck here. I have to diiferentiate between Mac OS(desktop browser) and iPad browser – newdeveloper Oct 13 '19 at 01:09
-
@newdeveloper try use Charles or netfox for inspecting the raw http request that the webview is making. There may be some headers that can help identify it. – neoneye Oct 13 '19 at 13:09
I think that you can just use the User-Agent
.
UPDATE
Page browsed using iPhone Safari
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7
I will try in a second with UIWebView
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Mobile/8B117
The difference is that the Safari one says Safari/6531.22.7
Solution
var isSafari = navigator.userAgent.match(/Safari/i) != null;

- 5,325
- 3
- 29
- 36
-
Yeah, but do you have any idea if there's a specific string or something to detect UIWebView in the User-Agent? So far I couldn't find anything... – Adam Tal Jun 20 '11 at 20:49
-
-
Nicolas the numbers will be different _at the moment_ because Safari and UIWebView (and "stand-alone"—i.e. home screen—web apps) use different engines. This changes in iOS 5. – Ben Jun 20 '11 at 21:21
-
I dont mean the numbers, i mean the `Safari/.....` itself is missing in the UIWebView – Nicolas S Jun 20 '11 at 21:22
-
@Nicolas: quite right, sorry I wasn't paying attention. I wonder if anyone could confirm whether this is still the case in iOS5? – Ben Jun 21 '11 at 08:05
-
Thanks, Nicolas, this seems to be the case indeed with all apps I've tested so far. Gonna test a little more to make sure I'm not missing anything (I'll test iOS5 as well just incase). – Adam Tal Jun 21 '11 at 12:17
-
So far I'm using this `var isSafari = navigator.userAgent.match(/Safari/i) != null;` (which returns true if the user is using actual Safari and not a 3rd party app). Hope this solution will last... – Adam Tal Jun 21 '11 at 21:24
-
I've tried all these solutions but didn't work in my case,
I was going to detect the Webview inside Telegram. I think it uses SFSafariViewController
.
I noticed Safari app changes all phone style texts to links with "tel:" prefix but a webview doesn't.
So, I used that.
test it here : jsfiddle
<!DOCTYPE html>
<html>
<head></head>
<body>
<ul id="phone" style="opacity:0">
<li>111-111-1111</li>
</ul>
</body>
</html>
<script>
var html = document.getElementById("phone").innerHTML;
if (navigator.platform.substr(0,2) === 'iP') {
if (html.indexOf('tel:') == -1)
alert('not safari browser');
else
alert('safari browser');
}
else
alert('not iOS');
</script>

- 3,542
- 1
- 34
- 38
-
1You should not rely on such trick because user or any other developers can disable telephone detection. – Бодров Андрей Nov 19 '18 at 13:41
-
@БодровАндрей I agree with you, but that was the only way I could find, I hope apple provide different User-Agent for that in future – Amir Khorsandi Nov 19 '18 at 14:06
-
Beware this is borken on iOS 13, because if Desktop Mode is used, then `navigator.platform === 'MacIntel'`. This especially affects iPadOS 13 Mobile Safari because it uses Desktop Mode by default. – robocat Jul 15 '19 at 05:17
-
@robocat you are right. its broken in iOS 13 iPad and I am right now stuck without a solution. Could you please help me with related question here https://stackoverflow.com/questions/58344491/request-browser-ismobiledevice-not-working-with-ipadair2-and-ios-13-0-1 – newdeveloper Oct 13 '19 at 01:13
Yeah:
// is this an IPad ?
var isiPad = (navigator.userAgent.match(/iPad/i) != null);
// is this an iPhone ?
var isiPhone = (navigator.userAgent.match(/iPhone/i) != null);
// is this an iPod ?
var isiPod = (navigator.userAgent.match(/iPod/i) != null);

- 64,767
- 30
- 146
- 239

- 3,669
- 36
- 38
-
14
-
@ThinkingStuff - Could you help me help diiferentiate between Mac OS(desktop browser) and iPad Safari browser - https://stackoverflow.com/questions/58344491/request-browser-ismobiledevice-not-working-with-ipadair2-and-ios-13-0-1 – newdeveloper Oct 13 '19 at 01:19
Updated
Tested on: April 2023, iOS 16.
Demo page: https://milen-yordanov.github.io/detect-ios-webview/index.html
See: https://github.com/milen-yordanov/detect-ios-webview
It is 2022 and Safari version is 15.4. None of the above solutions worked for me. There are two webview classes on iOS: WKWebView and SFSafariViewController. SFSafariViewController has the same userAgent as Safari. The solution I came up with relies on how height: 100vh
is handled on Mobile Safari. 100vh is the device screen height, not the document visible height.
For more info see:
https://developers.google.com/web/updates/2016/12/url-bar-resizing
https://bugs.webkit.org/show_bug.cgi?id=141832
https://github.com/bokand/URLBarSizing
So, on iOS a function like this detects a WebView mode.
function isWebView()
{
const htmlEl = document.getElementsByTagName('html')[0];
const bodyEl = document.getElementsByTagName('body')[0];
const oldHtmlHeight = htmlEl.style.height;
const oldBodyHeight = bodyEl.style.height;
htmlEl.style.height = "100vh";
bodyEl.style.height = "100%";
const webViewMode = document.documentElement.clientHeight === document.documentElement.scrollHeight;
// restore height
htmlEl.style.height = oldHtmlHeight;
bodyEl.style.height = oldBodyHeight;
return webViewMode;
}

- 61
- 1
- 2
-
-
here's a demo link, tried opening the link from twitter mobile app to open in webview but i get false for webview mode https://codesandbox.io/s/reverent-violet-n3jo8u – napster499 Jul 05 '22 at 14:38
-
Did not work for me when opening a link in Slack iOS app to show the in-app webView (within Slack app) with this code. Not sure if Slack is using WKWebView, SFSafariViewController or something else – emllnd Jan 04 '23 at 12:52
-
Demo page: https://milen-yordanov.github.io/detect-ios-webview/index.html – Milen Yordanov Apr 05 '23 at 08:51
-
@MilenYordanov, viewing the demo page in iPad Pro (12.9 2022 v16.1) in Chrome browser returns WebView: true. Shouldn't it supposed to return false? – Dimitris Leon May 09 '23 at 08:11
-
@DimitrisLeon, Chrome is an app that uses WebView component. You could use the userAgent string and a library like ua-parser-js to detect Chrome. – Milen Yordanov May 09 '23 at 10:44
Note that this approach does not work for iOS 10 and older versions.
For the Spring of 2018 none of proposed method worked for me so I came up with a new approach (which is not userAgent based):
const hasValidDocumentElementRatio =
[ 320 / 454 // 5, SE
, 375 / 553 // 6, 7, 8
, 414 / 622 // 6, 7, 8 Plus
, 375 / 812 // X
, 414 / 896 // Xs, Xr
].some(ratio =>
ratio === document.documentElement.clientWidth /
document.documentElement.clientHeight
)
const hasSafariInUA = /Safari/.test(navigator.userAgent)
const isiOSSafari = hasSafariInUA && hasValidDocumentElementRatio // <- this one is set to false for webviews
https://gist.github.com/BorisChumichev/7c0ea033daf33da73306a396ffa174d1
You are welcome to extend the code for iPad devices too, I think it should do the trick.
Worked well for Telegram, Facebook, VK webviews.

- 135
- 1
- 7
-
1For iPhone X it would be 375 / 812, also new: 414 / 896 for iPhone Xs Max/Xr – Olegdater Oct 11 '18 at 07:54
-
Neoneye's solution does not work anymore (see comments) and can be simplified. On the other hand, testing only "Safari" in the UA adresses much more than the ios handheld devices.
This is the test i'm using :
var is_ios = /(iPhone|iPod|iPad).*AppleWebKit.*Safari/i.test(navigator.userAgent);

- 316
- 2
- 6
Would suggest using Modernizr, and checking for indexeddb like this. You could cross-check that with user agent configuration (device, OS, browser, etc), but pure feature detection seems more recommended.

- 283
- 5
- 16
-
Sounds like a plan but what features would you test for? indexeddb is part of ie, chrome, firefox etc – SSED Apr 19 '16 at 15:35
Try With IOS 13
function mobileDetect() {
var agent = window.navigator.userAgent;
var d = document;
var e = d.documentElement;
var g = d.getElementsByTagName('body')[0];
var deviceWidth = window.innerWidth || e.clientWidth || g.clientWidth;
// Chrome
IsChromeApp = window.chrome && chrome.app && chrome.app.runtime;
// iPhone
IsIPhone = agent.match(/iPhone/i) != null;
// iPad up to IOS12
IsIPad = (agent.match(/iPad/i) != null) || ((agent.match(/iPhone/i) != null) && (deviceWidth > 750)); // iPadPro when run with no launch screen can have error in userAgent reporting as an iPhone rather than an iPad. iPadPro width portrait 768, iPhone6 plus 414x736 but would probably always report 414 on app startup
if (IsIPad) IsIPhone = false;
// iPad from IOS13
var macApp = agent.match(/Macintosh/i) != null;
if (macApp) {
// need to distinguish between Macbook and iPad
var canvas = document.createElement("canvas");
if (canvas != null) {
var context = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
if (context) {
var info = context.getExtension("WEBGL_debug_renderer_info");
if (info) {
var renderer = context.getParameter(info.UNMASKED_RENDERER_WEBGL);
if (renderer.indexOf("Apple") != -1) IsIPad = true;
};
};
};
};
// IOS
IsIOSApp = IsIPad || IsIPhone;
// Android
IsAndroid = agent.match(/Android/i) != null;
IsAndroidPhone = IsAndroid && deviceWidth <= 960;
IsAndroidTablet = IsAndroid && !IsAndroidPhone;
message = ""
if (IsIPhone) {
message = "Device is IsIPhone"
} else if (IsIPad) {
message = "Device is ipad"
} else if (IsAndroidTablet || IsAndroidPhone || IsAndroid) {
message = "Device is Android"
} else {
message = "Device is Mac || Windows Desktop"
}
return {
message: message,
isTrue: IsIOSApp || IsAndroid || IsAndroidTablet || IsAndroidPhone
}
}
const checkMobile = mobileDetect()
alert(checkMobile.message + ". Mobile: " + checkMobile.isTrue)

- 169,008
- 28
- 173
- 236

- 1,507
- 2
- 10
- 10
Last time I needed this (JUST for WebView purposes), I used this check:
function isIOS() {
return !/safari/.test( window.navigator.userAgent.toLowerCase()) || navigator.platform === 'iOS' || navigator.platform === 'iPhone';
}

- 1,604
- 20
- 20
-
This is broken in iOS13 Desktop Mode (platform no longer set to iPad or iPhone), and on iPod touch (platform can be "iPod" or "iPod touch"). – robocat Jul 15 '19 at 05:21
I have found a simple solution to detect iPhone or iPad. This works for me fine.
var is_iPad = navigator.userAgent.match(/iPad/i) != null;
var is_iPhone = navigator.userAgent.match(/iPhone/i) != null;
if(is_iPad || is_iPhone == true){
//perform your action
}

- 1,054
- 3
- 13
- 22
Working 15.02.19
Another solution for detecting webviews on iOS is checking for the support / existence of navigator.mediaDevices
.
if (navigator.mediaDevices) {
alert('has mediaDevices');
} else {
alert('has no mediaDevices');
}
In my case I didn't need to catch all webviews, but those that don't support camera / microphone input (Reminder: Alerts don't trigger in Webview, so make sure to change something in the dom for debug purposes)

- 633
- 2
- 8
- 32
-
-
@Chris What do you mean saying Telegram? A built-in browser that opens when you click a link in a message? It isn't a webview, it's an in-app browser that is similar to regular Safari and very different from a real webview. – Finesse May 14 '21 at 06:34
-
Seems like this code is the most reliable nowadays. But keep in mind that `navigator.mediaDevices` is absent on HTTP pages, so you can't use this method on HTTP pages. – Finesse May 14 '21 at 06:36
I know this code will check if it is being accessed from an icon added to the home screen:
if (window.navigator.standalone == true) {
//not in safari
}
but I'm not sure how it would react in a UIWebView. The only other solution I could think of is getting the user agent or using - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
and replacing the query string of the page you are accessing with something the page uses to identify that it is being accessed from a web view.

- 1,039
- 3
- 12
- 22
-
Thanks, I was using that code, but need more control. It seems to only detect the standalone mode, and considers the rest to be Safari. – Adam Tal Jun 20 '11 at 20:48
I don't think there's anything specific you can use in client-side Javascript, but if you have control over what the originating UIWebView can do, you might want to consider playing with the user agent string it generates, and testing for that in your client-side Javascript instead? A bit of a hack I know, but hey… This question may give some pointers on tweaking the user agent:
-
Thanks, Ben. Unfortunately I don't have control over the app's UIWebView user agent. – Adam Tal Jun 20 '11 at 20:47
@ Sod, Well i don’t have answer, but i am not convinced why you want to check, Since, browser engine whether its safari ( Browser ) or Application will be same its Webkit only, Yes Application can configure the Browser engine capabilities like, whether application wants to run JS or Display Image etc…
I believe, you must check for certain property whether Flash supported by Browser or whether browser displays image or not, or probably may be you would like to check the screen size,

- 3,765
- 10
- 48
- 97
-
you could discuss this in the comments. Anyway there are many cases to check wevbview – Yozi Apr 02 '19 at 11:14