---
title: Platform Detection
---
Helpers are built into Quasar to detect the Platform (and its capabilities) within the context of which the code is running.

> [!TIP]
> Based on your needs, you might also want to check the [Style & Identity > Visibility](../style/visibility.md) page to see how you can achieve the same effect using CSS alone. This latter method will render your DOM elements or components regardless of platform though, so choose wisely on how you want to handle the performance of your app.

## Platform API

### Props

- `userAgent` (string, optional)
  Client browser User Agent
  Examples:
    - `'mozilla/5.0 (macintosh; intel mac os x 10_14_5) applewebkit/537.36 (khtml, like gecko) chrome/75.0.3770.100 safari/537.36'`
- `is` (object, optional)
  Client browser details (property names depend on browser)
  Examples:
    - `{ chrome: true, version: '71.0.3578.98', versionNumber: 71, mac: true, desktop: true, webkit: true, name: 'chrome', platform: 'mac' }`
  Object shape:
    - `name` (string, optional)
      Browser name
      Examples: `'chrome'`
    - `platform` (string, optional)
      Platform name
      Examples: `'mac'`
    - `version` (string, optional)
      Detailed browser version
      Examples: `'71.0.3578.98'`
    - `versionNumber` (number, optional)
      Major browser version as a number
    - `mobile` (boolean, optional)
      Whether the platform is mobile
    - `desktop` (boolean, optional)
      Whether the platform is desktop
    - `cordova` (boolean, optional)
      Whether the platform is Cordova
    - `capacitor` (boolean, optional)
      Whether the platform is Capacitor
    - `nativeMobile` (boolean, optional)
      Whether the platform is a native mobile wrapper
    - `nativeMobileWrapper` (string, optional)
      Type of the native mobile wrapper
      Accepts: `'cordova'`, `'capacitor'`
    - `electron` (boolean, optional)
      Whether the platform is Electron
    - `bex` (boolean, optional)
      Whether the platform is BEX(Browser Extension)
    - `linux` (boolean, optional)
      Whether the operating system is Linux
    - `mac` (boolean, optional)
      Whether the operating system is Mac OS
    - `win` (boolean, optional)
      Whether the operating system is Windows
    - `cros` (boolean, optional)
      Whether the operating system is Chrome OS
    - `chrome` (boolean, optional)
      Whether the browser is Google Chrome
    - `firefox` (boolean, optional)
      Whether the browser is Firefox
    - `opera` (boolean, optional)
      Whether the browser is Opera
    - `safari` (boolean, optional)
      Whether the browser is Safari
    - `vivaldi` (boolean, optional)
      Whether the browser is Vivaldi
    - `edge` (boolean, optional)
      Whether the browser is Microsoft Edge
    - `webkit` (boolean, optional)
      Whether the browser is a Webkit or Webkit-based one
    - `android` (boolean, optional)
      Whether the operating system is Android
    - `ios` (boolean, optional)
      Whether the operating system is iOS
    - `ipad` (boolean, optional)
      Whether the device is an iPad
    - `iphone` (boolean, optional)
      Whether the device is an iPhone
    - `ipod` (boolean, optional)
      Whether the device is an iPod
- `has` (object, optional)
  Client browser detectable properties
  Examples:
    - `{ touch: false, webStorage: true }`
  Object shape:
    - `touch` (boolean, optional)
      Client browser runs on device with touch support
    - `webStorage` (boolean, optional)
      Client browser has Web Storage support
- `within` (object, optional)
  Client browser environment
  Examples: `{ iframe: false }`
  Object shape:
    - `iframe` (boolean, optional)
      Does the app run under an iframe?

### Methods

- `parseSSR(ssrContext: object): object`
  For SSR/SSG usage only, and only on the global import (not on $q.platform)
  Params:
    - `ssrContext` (object, required)
      SSR Context Object
  Returns: `object`
    Platform object (like $q.platform) for SSR/SSG usage purposes

### Vue Injection

Accessible via `$q.platform` (e.g., `this.$q.platform` in Options API or `useQuasar().platform` in Composition API).

## Usage

Usage inside a Vue component JS:

```js
import { useQuasar } from 'quasar'

setup () {
  const $q = useQuasar()

  $q.platform.is.mobile
}
```

Usage inside a Vue component template:

```js
$q.platform.is.cordova
```

You must import it when you use it outside of a Vue component :

```js
import { Platform } from 'quasar'
```

`Platform.is` by itself returns an object containing details about the current platform. For example when running Chrome on a MacOS desktop machine, `Platform.is` would return something similar to:

```js
{
  chrome: true,
  desktop: true,
  mac: true,
  name: "chrome",
  platform: "mac",
  version: "70.0.3538.110",
  versionNumber: 70,
  webkit: true
}
```

Now, let's say we want to render different components or DOM elements, based on the platform that the code is running under. We want to show something on desktop and something else on mobile. We would proceed like this:

```html
<div v-if="$q.platform.is.desktop"> I'm only rendered on desktop! </div>

<div v-if="$q.platform.is.mobile"> I'm only rendered on mobile! </div>

<div v-if="$q.platform.is.electron"> I'm only rendered on Electron! </div>
```

Example "Your device":

```vue
<template>
  <div class="q-mb-md">
    Browser User Agent: "<strong>{{ $q.platform.userAgent }}</strong
    >"
  </div>

  <q-markup-table flat bordered dense>
    <thead>
      <tr>
        <th class="text-left">Property</th>
        <th class="text-left">Value</th>
      </tr>
    </thead>

    <tbody>
      <tr
        v-for="(value, prop) in $q.platform.is"
        :key="prop"
        :class="
          value ? 'text-weight-bold platform-detection--row-highlight' : ''
        "
      >
        <td>{{ prop }}</td>
        <td>{{ value }}</td>
      </tr>
    </tbody>
  </q-markup-table>

  <div class="q-mt-md">
    The device which you are using to view this website
    <strong>{{ touch }}</strong> touch capability.
  </div>
</template>

<script setup>
import { useQuasar } from 'quasar'
import { computed } from 'vue'

const $q = useQuasar()
const touch = computed(() => ($q.platform.has.touch ? 'has' : 'does not have'))
</script>

<style lang="sass">
body
  &.body--light
    .platform-detection--row-highlight
      background-color: rgba(0,0,0,.05)
  &.body--dark
    .platform-detection--row-highlight
      background-color: rgba(255,255,255,.05)
</style>
```

## Properties

The following properties are available to the Platform object. It's not an exhaustive list though. See the API section below for more details.

| Property | Type | Meaning |
| --- | --- | --- |
| `Platform.is.mobile` | Boolean | Is the code running on a mobile device? |
| `Platform.is.cordova` | Boolean | Is the code running within Cordova? |
| `Platform.is.capacitor` | Boolean | Is the code running within Capacitor? |
| `Platform.is.nativeMobile` | Boolean | Is the code running within a native mobile wrapper(*Cordova/Capacitor*)? |
| `Platform.is.nativeMobileWrapper` | String | Name of the native mobile wrapper(*`'cordova'`, `'capacitor'`, or `undefined`*) |
| `Platform.is.electron` | Boolean | Is the code running within Electron? |
| `Platform.is.desktop` | Boolean | Is the code running on a desktop browser? |
| `Platform.is.bex` | Boolean | Is the code running in a browser extension? |
| `Platform.is.android` | Boolean | Is the app running on an Android device? |
| `Platform.is.cros` | Boolean | Is the app running on device with the Chrome OS operating system? |
| `Platform.is.ios` | Boolean | Is the app running on an iOS device? |
| `Platform.is.ipad` | Boolean | Is the app running on an iPad? |
| `Platform.is.iphone` | Boolean | Is the app running on an iPhone? |
| `Platform.is.ipod` | Boolean | Is the app running on an iPod? |
| `Platform.is.linux` | Boolean | Is the code running on a device with the Linux operating system? |
| `Platform.is.mac` | Boolean | Is the code running on a device with the MacOS operating system? |
| `Platform.is.win` | Boolean | Is the code running on a device with the Windows operating system? |
| `Platform.is.chrome` | Boolean | Is the code running inside the Google Chrome browser? |
| `Platform.is.firefox` | Boolean | Is the code running inside the Firefox browser? |
| `Platform.is.opera` | Boolean | Is the code running inside the Opera browser? |
| `Platform.is.safari` | Boolean | Is the code running inside the Apple Safari browser? |
| `Platform.is.vivaldi` | Boolean | Is the code running inside the Vivaldi browser? |
| `Platform.is.edge` | Boolean | Is the code running inside the Microsoft Edge browser? |
| `Platform.is.webkit` | Boolean | Is the code running on Webkit or webkit-based? |
| `Platform.has.touch` | Boolean | Is the code running on a touch capable screen? |
| `Platform.within.iframe` | Boolean | Is the app running within an IFRAME? |

> [!NOTE]
> Running on mobile means you can have this code running on a mobile device (phone or tablet) but with a browser, not within a Cordova wrapper.

## Note about SSR/SSG

When building for SSR/SSG, use only the `$q.platform` form. Alternatively, when on server-side, this is one more example of how you can use it:

```js
import { Platform } from 'quasar'

// you need access to `ssrContext`
function (ssrContext) {
  const platform = import.meta.env.QUASAR_SERVER
    ? Platform.parseSSR(ssrContext)
    : Platform // otherwise we're on client

  // platform is equivalent to the global import as in non-SSR builds
}
```

The `ssrContext` is available in [@quasar/app-vite Boot File](../quasar-cli-vite/boot-files.md). And also in the [@quasar/app-vite preFetch](../quasar-cli-vite/prefetch-feature.md) feature, where it is supplied as a parameter.

The reason for all this is that in a client-only app, every user will be using a fresh instance of the app in their browser. For server-side rendering we want the same: each request should have a fresh, isolated app instance so that there is no cross-request state pollution. So Platform needs to be bound to each request separately.
