v147 · Demo 4 · PWA
Push Subscription Migrator
Push notification subscriptions are the hardest part of a PWA origin migration. This tool reads your current PushSubscription, walks through the 3-step migration flow, and shows how the applicationServerKey transfer approach works across browsers.
Migration flow
Old SW sends migration push
Old origin's service worker sends a final push message containing the new origin URL. The push payload includes a migrateTo field that the page reads on receipt.
User visits new origin
The migration push opens or focuses a tab at the new origin. The new page detects it's a migration visit (via URL param or storage flag) and prompts for push re-subscription.
pendingNew SW subscribes
New origin's service worker calls pushManager.subscribe({ applicationServerKey }). Server updates its subscription database. Old subscription is unregistered.
Walk through all 3 migration steps interactively. Each step logs what would happen in a real deployment.
Step 3 attempts a real pushManager.subscribe() call if push is available.
applicationServerKey transfer approach
When both origins share the same VAPID key pair (same applicationServerKey), some browsers
allow the subscription endpoint to be reused at the new origin. This is the smoothest migration path.
// Step 1: Old origin - read current sub and include in migration push
const oldSub = await reg.pushManager.getSubscription();
const endpoint = oldSub.endpoint;
const p256dh = btoa(String.fromCharCode(...new Uint8Array(oldSub.getKey('p256dh'))));
const auth = btoa(String.fromCharCode(...new Uint8Array(oldSub.getKey('auth'))));
// Server sends push with migration payload:
// { migrateTo: 'https://new.example.com', endpoint, p256dh, auth }
// Step 2: New origin service worker - re-subscribe with same VAPID key
const newReg = await navigator.serviceWorker.ready;
const newSub = await newReg.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: SAME_VAPID_PUBLIC_KEY,
});
// Step 3: Old SW unsubscribes
await oldSub.unsubscribe();
Browser support for applicationServerKey transfer
| Browser | Push subscribe | Same VAPID key reuse | Auto-migration | Notes |
|---|---|---|---|---|
| Chrome 147+ | Yes | Yes | Via migrate_from + allow_migration | Full same-site PWA origin migration handshake support |
| Chrome 109–146 | Yes | Partial | No | Must manually re-subscribe; no manifest migration |
| Firefox | Yes | Partial | No | New endpoint always generated; server must update |
| Safari 16.4+ | Yes | No | No | Subscription is fully origin-bound; must re-subscribe |
| Edge (Chromium) | Yes | Yes | Follows Chrome | Same as Chrome 147+ |
| Samsung Internet | Yes | Partial | No | Re-subscribe required at new origin |
references
implementation reference
Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗