v150 · PWA · Migration Demo
Migration Demo
Reads your current install context and shows the manifest and well-known fields Chrome uses during PWA origin migration. This page also clarifies which signals are directly involved in migration and which APIs only expose surrounding install context.
Origin migration requires both sides to declare the handoff: the destination manifest includes
migrate_from, and the old origin hosts a /.well-known/web-app-origin-association file with allow_migration for the destination app ID. Chrome performs this verification before offering the migration.
current page context
install environment
display-mode
detecting…
running as PWA
detecting…
origin
—
manifest link
—
related installed apps
Uses navigator.getInstalledRelatedApps() as a surrounding install-context probe. PWA origin migration itself is manifest-driven by migrate_from and allow_migration, not by this API.
migration verification steps
Chrome performs these checks before migrating an installed PWA to the new origin:
-
1
Destination
manifest.jsonincludes a stableidscoped to the new origin -
2
Destination
manifest.jsonincludesmigrate_fromnaming the installed old app ID -
3
Old origin hosts
/.well-known/web-app-origin-associationwithallow_migration: trueunder the destination app ID - 4 Chrome confirms the origins are same-site and can fetch the destination manifest plus old-origin association file
-
5
Chrome presents an update-style migration prompt, or a blocking prompt when
behavior: "force"is set
code
// Check for related installed apps
// (Chrome checks this during origin migration too)
if ('getInstalledRelatedApps' in navigator) {
const apps = await navigator.getInstalledRelatedApps();
if (apps.length) {
// A related app is installed — useful install context,
// but PWA origin migration is driven by manifest fields.
for (const app of apps) {
console.log(app.platform, app.url, app.version);
}
} else {
// No related apps — fresh install scenario
}
}
// Detect if running as installed PWA
const isInstalled = window.matchMedia('(display-mode: standalone)').matches
|| window.matchMedia('(display-mode: minimal-ui)').matches
|| window.matchMedia('(display-mode: window-controls-overlay)').matches
|| navigator.standalone === true;
see also
implementation reference
Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗