Skip to content

Concept in Installation

Several PWAs on one origin

Published

Limited availabilityNot supported in Firefox (Desktop), Firefox (Android)W3C

A single origin can host distinct installed web applications with separate manifests. Use the manifest id for application identity and scope for the navigation boundary of each application context (Web Application Manifest, W3C).

A processed id is a URL with the same origin as the processed start_url. A user agent should treat a manifest with an identity that does not match an installed application as a distinct application. A matching identity signals that the manifest replaces the installed application’s manifest. If id is missing, empty, invalid, or cross-origin, its processed value remains the processed start_url (id member, W3C).

scope is a separate URL. A document is within scope when its URL has the same origin as the scope URL and its path starts with the scope URL’s path. If scope is missing, empty, invalid, or does not contain start_url, the default is start_url with its filename, query, and fragment removed (scope member, W3C).

Because matching uses a path prefix, "/sales" also contains /sales-report; use "/sales/" when the intended boundary is that directory. Two application scopes can contain the same URL, but scope does not identify an installed application. Use distinct, stable id values for identity, and choose non-overlapping scope paths when each URL should remain within one application context.

The cited BCD dataset records id support from Chrome 96, Safari 17 on macOS, and Safari 16.4 on iOS. Edge and Samsung Internet use mirrored data; that file lists no explicit versions for them. Firefox parses the member without applying it (BCD manifests.webapp.id).

Give sales and support applications separate identities and directory boundaries when serving them from the same origin.

Link this manifest from documents that install the sales application.

{
"name": "Acme Sales",
"id": "/apps/sales",
"start_url": "/sales/",
"scope": "/sales/",
"display": "standalone"
}

The id is an identifier rather than a navigation target, so the specification does not require it to be within scope.

The support manifest uses another identity and a non-overlapping path prefix.

{
"name": "Acme Support",
"id": "/apps/support",
"start_url": "/support/",
"scope": "/support/",
"display": "standalone"
}

Keep the two id values stable when changing launch URLs or manifest URLs within the same origin.

Detecting the linked manifest with a fallback

Section titled “Detecting the linked manifest with a fallback”

Checking the document does not reproduce the user agent’s id or scope processing. It detects whether the browser reports support for the manifest link type and the current document declares a manifest link. If either check fails, it retains ordinary website navigation. The link’s relList is a DOMTokenList; its supports() method reports whether a token is supported (DOMTokenList.supports(), MDN). The rel~= selector matches manifest within the space-separated rel tokens defined by HTML.

const probe = document.createElement('link');
const supportsManifestLink = typeof probe.relList?.supports === 'function'
&& probe.relList.supports('manifest');
const manifestLink = document.querySelector('link[rel~="manifest"][href]');
if (!supportsManifestLink || !manifestLink) {
document.documentElement.dataset.navigation = 'website';
} else {
document.documentElement.dataset.navigation = 'app-candidate';
console.info(`Linked manifest: ${manifestLink.href}`);
}

This check detects the document’s declaration only. It does not claim that the browser processes id, that the application is installed, or that the current URL is within the processed scope.

Specifications

SpecificationStatus
manifest: idW3C
  • Legend
  • Yes
  • Partial
  • Flag
  • No
  • Unknown
Browser / PlatformSupportVersionsConfidenceSourceNotes
Chrome (Desktop)#Yes96highsource—
Chrome (Android)#Yes96highsource1
Edge (Desktop)#Yes96highsource2
Firefox (Desktop)#No—highsource3
Firefox (Android)#No—highsource4
Safari (macOS)#Yes17highsource—
Safari (iOS)#Yes16.4highsource—
Samsung Internet#Yes17.0highsource5
WebView (Android)#Yes96highsource6
  1. Derived by browser-compat-data mirroring from Chrome.
  2. Derived by browser-compat-data mirroring from Chrome.
  3. The property parses, but has no effect.
  4. No Firefox for Android support is recorded in browser-compat-data.
  5. Derived by browser-compat-data mirroring from Chrome Android.
  6. Derived by browser-compat-data mirroring from Chrome Android.

Source data: /compatibility/manifest-id.json · Global usage: 93 % (StatCounter 2026-09, CC BY-SA 4.0)

Source: spec · MDN · Last verified 2026-10-03 · Confidence: high (computed from sources)