# getInstalledRelatedApps()

> How navigator.getInstalledRelatedApps() reports which entries of the manifest's related_applications are installed on the device, the verification each platform demands, the empty-array and InvalidStateError cases, and a fallback.

`navigator.getInstalledRelatedApps()` resolves with the subset of the calling web app's manifest `related_applications` that is installed on the device, so a site can hide its own install button or deep-link into a native counterpart. Chrome 84 and Samsung Internet 14 on Android report Play apps and installed PWAs; Chrome 85, Edge 85, and Opera 71 on Windows report UWP apps only, and the same browsers on macOS, Linux, and ChromeOS resolve with an empty array; Firefox and Safari have not implemented it (BCD `api.Navigator.getInstalledRelatedApps`).

## Syntax

```js
const apps = await navigator.getInstalledRelatedApps();
```

The method is `[SecureContext]`, so it is absent on plain HTTP origins, and it is defined only on `Navigator`, not on `WorkerNavigator`.

## Parameters

None. The promise fulfils with an array of `RelatedApplication` dictionaries, one per installed match, each carrying the fields below.

| Field | Type | Description |
|---|---|---|
| `platform` | `string` | The store or ecosystem: `"play"`, `"windows"`, `"webapp"`, `"chrome_web_store"`, `"chromeos_play"`, `"f-droid"`, or `"amazon"`. Copied from the manifest entry. |
| `id` | `string`, optional | The platform-specific identifier (Android package name, UWP package family name). |
| `url` | `string`, optional | The entry's `url` from the manifest; for `"webapp"` it is the related PWA's manifest URL. |
| `version` | `string`, optional | The installed version where the platform exposes one. |

A match requires both halves of the relationship: the manifest entry on the calling site, and a declaration on the other app pointing back. An Android app does so with Digital Asset Links (`asset_statements` in its resources, verified against the site's `/.well-known/assetlinks.json`); a UWP app does so with URI handlers; a related PWA does so with a `related_applications` entry of its own, or with `assetlinks.json` when it is outside the caller's scope.

## Exceptions

- `InvalidStateError`: the method was called from a document that is not the top-level browsing context, such as an `<iframe>`, or from a document that is no longer fully active (spec, "getInstalledRelatedApps()" steps 1 and 2).
- `TypeError`: thrown synchronously in Firefox and Safari, where `navigator.getInstalledRelatedApps` is `undefined`, and on insecure origins in every browser.

An empty array is not an error. It is the result when `related_applications` is missing, when nothing listed is installed, when the back-reference (asset links or URI handler) fails verification, and on Chromium desktop builds other than Windows.

:::observed
In Chrome on macOS (English UI), `await navigator.getInstalledRelatedApps()` in the console resolves to `[]` even for a site whose manifest lists an installed `"webapp"` entry, which is the documented non-Windows desktop behaviour; in Firefox the same line throws `TypeError: navigator.getInstalledRelatedApps is not a function`, and Safari throws a `TypeError` with its own wording. Chrome caps the lookup at the first three `related_applications` entries, so entries beyond the third are not reported (Chrome capability guide).
:::

## Examples

Both examples assume a manifest whose `related_applications` names the Android app `com.example.app` and the site's own PWA.

### Hiding the install button when the Play app is present

The manifest declares the relationship; the page checks it before deciding whether to show a web install affordance. Because the method only answers for the first three entries, list the apps that matter most first.

```json
{
  "related_applications": [
    { "platform": "play", "id": "com.example.app",
      "url": "https://play.google.com/store/apps/details?id=com.example.app" },
    { "platform": "webapp", "url": "https://example.com/manifest.json" }
  ],
  "prefer_related_applications": false
}
```

```js
async function decideInstallUi() {
  const apps = await navigator.getInstalledRelatedApps();
  if (apps.some((app) => app.platform === 'play')) {
    installButton.hidden = true;             // the native app is already there
    openInAppLink.hidden = false;            // offer the deep link instead
  } else if (apps.some((app) => app.platform === 'webapp')) {
    installButton.hidden = true;             // this PWA is installed from another browser or profile
  }
}
```

Keep `prefer_related_applications` at `false` unless the native app should replace the PWA: when it is `true`, Chrome's install UI offers the store listing instead of installing the web app.

### Detecting support and falling back to the install prompt

Where the method is absent or returns nothing, the page has no installed-state signal from other apps and should fall back to its normal install flow and to the `display-mode` check for its own installed state.

```js
async function relatedAppInstalled() {
  if (!('getInstalledRelatedApps' in navigator)) return false;   // Firefox, Safari, HTTP
  try {
    const apps = await navigator.getInstalledRelatedApps();
    return apps.length > 0;
  } catch (error) {
    if (error.name === 'InvalidStateError') return false;        // called inside an iframe
    throw error;
  }
}

if (!(await relatedAppInstalled())) {
  showInstallAffordance();   // beforeinstallprompt flow, or Share-sheet instructions on iOS
}
```

The `false` branch is the correct degraded behaviour: a browser that cannot answer the question should behave as if no related app is installed, which at worst shows an install button to a user who already has the native app.

## See also

- [Get Installed Related Apps API specification](https://wicg.github.io/get-installed-related-apps/spec/) (wicg.github.io)
- [Is your app installed? getInstalledRelatedApps() will tell you!](https://developer.chrome.com/docs/capabilities/get-installed-related-apps) (developer.chrome.com)
- [getInstalledRelatedApps() browser support](/compatibility/get-installed-related-apps/)
- [`related_applications` manifest member](/reference/manifest/related-applications/)
- [beforeinstallprompt event](/reference/installation/install-prompt/)
- [The N+1 install problem](/reference/installation/n-plus-one/)