How to determine if browser or app

Ok cool, so that explains the what. I don’t know the platform well enough to know if that’s intended behavior. Given this though, is there a way to differentiate between the app version and a mobile browser?

In case anyone else needs to do this the solution I’ve settled on is a pretty simple.

It seems that the apps (both android and ios at least) serve from the file:// protocol so

this.isApp = !document.URL.startsWith('http');
12 Likes

That is a nice workaround.

Created a ticket for this here:

1 Like

A related issue - chrome on iOS is returning only ‘core’ as the platform. See screenshot below. Any ideas why or a workaround.

I am trying to determine if the site is running on a desktop vs a mobile device. It works fine on safari and chrome on android. For some reason chrome on iOS returns core.

IMG_6311|281x500

Please create an issue about this here: https://github.com/ionic-team/ionic/issues Include the screenshot and a bit of description what code you are executing. Thanks.

As a solution, you might want to look at the underlying code and see if you can copy some into your .ts file and make it react to Chrome iOS correctly.

Hmm, with the WKWebView my above workaround doesn’t work anymore as ios uses http://localhost:8080 to serve from.

So the less nice thing can still be done like this

this.isApp = (!document.URL.startsWith('http') || document.URL.startsWith('http://localhost:8080'));

It works so long as your local ionic serve doesn’t use the same port :slight_smile:

7 Likes

Thnx for it, it was really needed…

great !!! worked like charm !!! thank you :slight_smile:

Thats nice, I’ve added this to difference between browser and electron

public isBrowser() {
return (this._platform.is(‘core’) || this._platform.is(‘mobileweb’)) && this.hasHttp();
}

public isDesktop() {
    return this._platform.is('core') && !this.hasHttp();
}
1 Like

String.startsWith is unsupported in IE. I recommend using indexOf instead:

const isApp = document.URL.indexOf('http') !== 0;

What I do and works perfectly is this:

this.isApp = ((!document.URL. indexOf('http') !==0) || (document.URL. indexOf('http://localhost:8080') !== 0));

Just to explain the logic behind the http trick, there are actually two scenarios that needs to be addressed separately:

  1. Developing and testing on browser
    $ ionic serve --lab

  2. Testing / Debug on cordova emulator using a “browser device”
    $ ionic cordova run browser

  • The second is needed to debug cordova plugins more efficiently then in real device, as they doesn’t exist on ionic serve, as its port can change, i suggest using :
    document.URL.startsWith(‘http://localhost:80’) instead of the full port.

  • As both of them run in browser, I suggest running ionic serve as local “fake” domain, registered in /etc/hosts
    such as dev.example.com pointing to local dev ip, in this case, the dev will not be identified as App.

Final code:
this.isApp = (!document.URL.startsWith('http') || document.URL.startsWith('http://localhost:80'));

Hello,
regarding the css depending on the platform,
if ios = .ios, android = md then desktop browser = ???

thank you in advance

Not sure I completely understand your question but if its running on desktop browser it will be “core” which uses md (material design).

I’ve added a check for Angular isDevMode() to your solution, this should be true if running ionic serve but false when running your app in production on a device (ionic cordova build ios --prod):

import { isDevMode } from '@angular/core';

 isApp(): boolean {
    return (!document.URL.startsWith('http') || document.URL.startsWith('http://localhost:8080') || isDevMode());
  }

Seems to be working for me so far, of course this will fail if you don’t do a --prod build for your web or app builds.

EDIT

Use the following for IE support as mentioned above:

import { isDevMode } from '@angular/core';

 isApp(): boolean {
    return (document.URL.indexOf('http') !== 0 || document.URL.indexOf('http://localhost:8080') === 0 || isDevMode());
  }

}

EDIT 2

Okay so those don’t actually work on Android as the webview serves the app on http://localhost and on iOS it seems to be served on ionic://localhost so here is my latest solution:

import { Injectable } from '@angular/core';

@Injectable()
export class EnvironmentProvider {

  public isApp(): boolean {
    return (
      document.URL.indexOf('http://localhost') === 0 || 
      document.URL.indexOf('ionic') === 0 || 
      document.URL.indexOf('https://localhost') === 0
    );
  }

  public isBrowser(): boolean {
    return !this.isApp();
  }

}

It should work on iOS 10+ using the cordova-plugin-ionic-webview and Android now.

1 Like

Don’t make it so complicated. The easiest an most common way:

if (this.platform.is(cordova)) {
   // App
}
if (!this.platform.is(cordova)) {
   // Probably Browser
}

@mariusbolik - that’s not a reliable test for all cases, if you follow the thread from the beginning you will see that the browser build of my app (and potentially other peoples) uses cordova.

I’ve found for me the most common way to check if the App runs in Browser (Dev) or on a Device (Dev / Prod). Since ionic serve runs locally with port 8100, we can check if this port is used / available.

You should not forget, that the location protocol on Android can be http too.

    /**
	 * @private
	 * @function isAppOnDevice
	 * @description Simply check, if the environment is a device or desktop browser
	 * @return {boolean}
	 */
	private isAppOnDevice(): boolean {
		if (window.location.port === '8100') {
			return false;
		} else {
			return true;
		}
	}

Or if you want to assign it to a var:

export const APP_IS_ON_DEVICE: boolean = !(window.location.port === '8100');

Hope it helps someone.

Cheers
Unkn0wn0x

1 Like

For some reason my app that was using the solution below has stopped working:

isApp(): boolean {
    return (document.URL.indexOf('http') !== 0 || document.URL.indexOf('http://localhost:8080') === 0);
  }

Now I´m using your solution @ Unkn0wn0x and it works propertly, thank you so much!

i am using cordova.platformId for this.
this delivery ios, android or browser - depending on the case.

1 Like