32

In Cordova you had immediate access to process.env.CORDOVA_PLATFORM is there something similar in Capacitor?

I'm looking to conditionally load some functions on startup and don’t want to block rendering waiting for async Device.getInfo to come back.

For example I want to determine immediately wether to import a script that make's native keyboard modifications, but I don't want to import this script if we are running on web

try {
  const { Keyboard } = Plugins
  Keyboard.setAccessoryBarVisible({ isVisible: true })
} catch (error) {
  // Keyboard isn't available on web so we need to swallow the error
}

I'm using vue-cli

Hasta Dhana
  • 4,699
  • 7
  • 17
  • 26
Titan
  • 5,567
  • 9
  • 55
  • 90

8 Answers8

34

The answers so far are all correct, if you take a look into the Capacitors source code, there a few ways available, which can be used (but are undocumented for now):

  • Capacitor.getPlatform(); // -> 'web', 'ios' or 'android'
  • Capacitor.platform // -> 'web', 'ios' or 'android' (deprecated)
  • Capacitor.isNative // -> true or false

Be aware, that the method Capacitor.isPluginAvailable('PluginName'); only returns if the plugins is available or not (obviously) but important here, it does not tell you, if the method you want to execute after checking the availability is for your platform available.

The documentation of the Capacitor Plugins is not completed (yet).

Example (code), for the plugin StatusBar:

// Native StatusBar Plugin available
if (Capacitor.isPluginAvailable('StatusBar')) {

    // Tint statusbar color
    StatusBar.setBackgroundColor({
        color: '#FF0000'
    });

}

This would result in an error on iOS, since this method is not available there, on Android it works fine so far.

That means, that you need to implement a check of the Plugin and Platform combination by yourself (for now), may this will be improved in the future by Ionic / Capacitor itself.

Something like:

// Native StatusBar available
if (Capacitor.getPlatform() === 'android' && Capacitor.isPluginAvailable('StatusBar')) {

    // Tint statusbar color
    StatusBar.setBackgroundColor({
        color: this.config.module.GYMY_MODAL_STATUSBAR_HEX_STRING
    });

}

One more thing, you are not able to check, whether the method exists within this plugin (f. e. for the code above setBackgroundColor) as it is available, but throws an error (Error: not implemented) on a platform, which does not support it.

Hope I could help some of you guys.

Cheers Unkn0wn0x

Steffan
  • 704
  • 1
  • 11
  • 25
Unkn0wn0x
  • 1,031
  • 1
  • 12
  • 14
  • Very well explained. Even though the correct answer makes bundling more efficient, this explanation is more valid imho. – Rip3rs Dec 12 '20 at 12:30
  • I do agree, but I think that mentioning how you can import Capacitor would be helpful. Here it goes: `import { Capacitor } from '@capacitor/core';` – Brhaka Jul 13 '23 at 11:18
18

There is also the property Capacitor.isNative which you could use to determine whether the WebApp is running in Capacitor or in the Web.

https://github.com/ionic-team/capacitor/blob/master/core/src/definitions.ts

Update: In Capacitor V3 you can use Capacitor.isNativePlatform() for this. https://capacitorjs.com/docs/v3/core-apis/web#isnativeplatform

laberning
  • 769
  • 7
  • 19
17

As of Capacitor 3, you can use the following method to determine if it's running on a native device ("iOS" - "Android") or not ("web").

import { Capacitor } from '@capacitor/core';
if(Capacitor.isNativePlatform()) {
    // Platform is mobile
} else {
    // Platform is not mobile
}

Official documentation link. https://capacitorjs.com/docs/core-apis/web#isnativeplatform

Ibrahim Awad
  • 498
  • 1
  • 6
  • 13
12

Found it undocumented: Capacitor.platform

Capacitor.platform could be for example web ios android

Also if you wanted to know if you were running native before loading Capacitor, i.e you wanted to reduce bundle size by not including Capacitor on the web.

window.origin.includes('capacitor://')

Titan
  • 5,567
  • 9
  • 55
  • 90
  • 4
    @Andreas Given the question, it looks like the answer (this is the OP after all), though more elaboration *would* make it more useful – CertainPerformance Sep 02 '19 at 02:46
  • window.origin.includes('capacitor://') evaluates to false for me on my Android Capacitor build (capacitor 3.0.2). – Alex Jun 30 '21 at 16:16
  • 3
    On Android capacitor runs at `http://localhost` and on iOS it's `capacitor://` so `window.origin.includes` will not work cross platform – webdog Sep 29 '21 at 18:01
  • Well, presumably a web app prod deploy won't have `http://localhost` in `window.origin`, so there is some possibility here to target the 3 platforms effectively. On your local dev environment you can (should) implement a `mywebsite.local` domain as well. In any case, it's still risky and better to follow the other answers. – Kalnode Jan 11 '23 at 03:24
5

You can now use Capacitor.isPluginAvailable('plugin name') to make this check, e.g., :

import { Capacitor, Plugins } from '@capacitor/core';
const { Keyboard } = Plugins;
...
const isAvailable = Capacitor.isPluginAvailable('Keyboard');

if (isAvailable) {
  Keyboard.setAccessoryBarVisible({ isVisible: true })
}

Brownoxford
  • 51
  • 1
  • 2
4

You can see all of those on official doc here: https://capacitorjs.com/docs/basics/utilities#getplatform

if (Capacitor.getPlatform() === 'ios') {
  // do something
}

if (Capacitor.isNative) {
  // do something
}
Sampath
  • 63,341
  • 64
  • 307
  • 441
0

I would say Device.getInfo() is the only reliable way of checking device's platform in capacitor based project.

Because the implementation of getPlatform(), Capacitor.platform is based on user agent of ui client. That means, if you opened your app on web and select developer tools then select mobile view, in this case it identify your platform as ios or android depending on which one you selected in dev tools instead of 'web'

Parameshwar Ande
  • 807
  • 1
  • 8
  • 16
  • Are you sure that "Capacitor.platform is based on user agent of ui client." ? Because when I use any mobile emulator in dev-tools I still have platform equal `web`. So this means that Capacitor.platform is reliable, no ? – Stephane L Mar 24 '21 at 08:01
  • As for I know, Capacitor.Platform uses useragent. Ref: https://github.com/ionic-team/ionic-framework/blob/master/core/src/utils/platform.ts – Parameshwar Ande Mar 25 '21 at 06:28
0
Capacitor.isNativePlatform()

This returns a boolean if the platform is native or not.

Android and IOS return true

Otherwise it returns false

simon
  • 41
  • 6