Skip to content

Manifest · Manifest member

id manifest member

Published

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

id is the string that identifies the web application. Before the member existed, each browser derived identity from something else, usually start_url, so changing the launch URL made the manifest describe a new app and a later install sat beside the old one. With id set, the identity and the launch URL are separate values: start_url can move, the identity stays.

Chrome 96, Edge 96, Samsung Internet 17.0, Safari on iOS 16.4, and Safari 17 on macOS process the member (BCD html.manifest.id). Firefox 157 parses it without effect, because Firefox on desktop installs no web apps from the manifest. Browsers that ignore id keep their previous identity rule, so adding the member never breaks an install elsewhere.

  • Type: string, parsed as a URL against the origin of start_url. A value that resolves to another origin is rejected; Chromium logs property 'id' ignored, should be same origin as document. and falls back to the default.
  • Default: the resolved start_url. An absent, empty, or unparsable id couples the identity to the launch URL, which is the situation the member exists to avoid.
  • Example value: "/?homescreen=1", which for an app on https://example.com resolves to https://example.com/?homescreen=1.

The resolved value is compared with the identity of every installed app when a manifest is processed. A match means “update this app”; no match means “a new app”. Because the comparison is on the full resolved URL, "/" and "/?v=2" are different apps, and a value should be chosen once and left alone. Chromium’s update check runs once a day for an installed app and applies most field changes only after every window of the app closes (web.dev, “How Chrome handles updates to the web app manifest”); a changed start_url is accepted as an update only when id is present and unchanged.

navigator.getInstalledRelatedApps() does not read id: it reports related native apps and, on Chrome 80+, a PWA listed in related_applications with platform: "webapp", matched by manifest URL rather than by id.

The manifests below show the value to pick before the first release, the change id makes safe, and how to recover an identity for an app that shipped without one.

Fixing the identity before the first install

Section titled “Fixing the identity before the first install”

A short root-relative path is enough; the member resolves against the origin of start_url, so a scheme and host add nothing. The launch URL carries an analytics parameter that may change later without touching the identity.

{
"name": "Ledger",
"id": "/",
"start_url": "/app/?source=pwa",
"scope": "/app/",
"display": "standalone"
}

Chrome 96+ and Safari 16.4+ record the identity as https://example.com/; a later manifest with "start_url": "/dashboard/?source=pwa" updates the installed app instead of creating a second one.

Moving start_url without a duplicate install

Section titled “Moving start_url without a duplicate install”

With the identity fixed, a redesign that changes the launch path only edits start_url and scope. The identity line is the one that must not move.

{
"name": "Ledger",
"id": "/",
"start_url": "/home/",
"scope": "/",
"display": "standalone"
}

On Chrome 155 the installed app picks up the new start_url at the next daily manifest check and applies it after the last app window closes; on a browser that ignores id, the same change still works as long as that browser never keyed the identity on start_url.

Adopting id for an app that shipped without one

Section titled “Adopting id for an app that shipped without one”

An app installed before id was declared has the identity Chromium computed from its start_url. To keep those installs, set id to exactly the computed value shown in DevTools; the script below reads the manifest the page links and prints the value to copy, falling back to a note when the manifest fetch fails.

async function suggestedId() {
const link = document.querySelector('link[rel="manifest"]');
if (!link || !('fetch' in window)) return null; // Nothing to inspect.
const manifest = await fetch(link.href).then((r) => r.json()).catch(() => null);
if (!manifest) return null;
if (manifest.id) return new URL(manifest.id, location.origin).href;
return new URL(manifest.start_url ?? '/', link.href).href; // Chromium's default identity.
}
const id = await suggestedId();
console.log(id ? `Set "id" to ${new URL(id).pathname + new URL(id).search}` : 'Manifest not readable');

For "start_url": "/app/?source=pwa" the printed value is /app/?source=pwa; declaring that string as id freezes the identity existing users already have, after which start_url is free to change.

Specifications

SpecificationStatus
manifest: idW3C
Web Application Manifest: start_url memberW3C
  • 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 InternetYes17.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: 90 % (StatCounter 2026-05)

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