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.

Push subscriptions are origin-bound. During a PWA origin migration, users must re-subscribe at the new origin. This demo walks through the recommended migration handshake and reads your real PushManager subscription data where available.

Migration flow

1

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.

pending
2

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.

pending
3

New SW subscribes

New origin's service worker calls pushManager.subscribe({ applicationServerKey }). Server updates its subscription database. Old subscription is unregistered.

pending
Current push subscription
subscription endpoint not yet read — click "Read subscription"
p256dh key
auth key
applicationServerKey
expirationTime
SW support checking…
Push support checking…
Simulate migration

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.

Click "Simulate Migration" to walk through all 3 steps…

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 ↗