v147 · PWA · demo

Migration Timeline

Walk through each stage of a PWA origin migration — from the developer publishing the manifest declarations to Chrome silently updating the installed app on the user's device.

Step 0 of 6 — press Next to begin
Developer · destination origin
Declare the predecessor in the new manifest
The destination app publishes a stable id and a migrate_from entry that names the installed app on the old origin.
// https://app.newexample.com/manifest.json { "id": "https://app.newexample.com/app/", "start_url": "https://app.newexample.com/app/index.html", "migrate_from": [{ "id": "https://app.oldexample.com/", "behavior": "suggest", "install_url": "https://app.oldexample.com/install.html?noredirect=true" }] }
Developer · old origin
Authorize the destination app id
The old origin confirms the relationship in /.well-known/web-app-origin-association with allow_migration: true. Chrome ignores a one-sided destination claim.
// https://app.oldexample.com/.well-known/web-app-origin-association { "https://app.newexample.com/app/": { "allow_migration": true } }
Browser · background
User launches installed app from old origin
The user has the PWA installed at app.oldexample.com. During the update check, Chrome can follow the destination manifest's install_url if old app routes already redirect.
// Chrome internally: // 1. Fetch app.oldexample.com/manifest.json // 2. Read optional migrate_to: // { id: "https://app.newexample.com/app/" } // 3. Fetch destination manifest and migrate_from // → initiate validation
Browser · validation
Browser validates the two-sided handshake
Chrome checks that migrate_from names the old app id, the old-origin association file authorizes the destination app id, and both origins stay same-site and HTTPS.
// Chrome internally: // 1. Fetch app.newexample.com/manifest.json // 2. Check migrate_from[0].id === "https://app.oldexample.com/" ✓ // 3. Fetch /.well-known/web-app-origin-association from old origin // 4. Check allow_migration for "https://app.newexample.com/app/" ✓ // 5. Check same-site and HTTPS ✓ // → validation passed
Browser · update
Chrome transfers the installed app identity
The browser silently updates the installed app record to point to the new origin. The app icon, name, and position on the home screen / taskbar are preserved. No user prompt required.
// Result in browser's app registry: // Before: { origin: "app.oldexample.com", name: "My Great App" } // After: { origin: "app.newexample.com", name: "My Great App" } // // Home screen icon unchanged ✓ // Permissions preserved ✓ // No reinstall needed ✓
User experience
User opens app — now served from new origin
Next time the user taps the app icon, Chrome loads the new origin transparently. The user sees no change — same icon, same name, same experience. The migration is complete.
// User perspective: nothing changed // Developer perspective: app now at new origin // Old origin can redirect or sunset gracefully

see also

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗