PWA Origin Migration in Chrome 150: Change Domains Seamlessly
Technical Guide · Updated June 2026

PWA Origin Migration in Chrome 150:
Change Domains Without Losing Users

A deep dive into Chrome 150's new PWA origin migration feature — the two-way handshake, suggest vs force modes, security considerations, and a complete step-by-step migration checklist for developers.

Oleg Maximov June 6, 2026 12 min read

Introduction: The Problem PWA Origin Migration Solves

Since Progressive Web Apps were introduced, one of their most painful limitations has been the tight coupling between a PWA's identity and its web origin. If you deployed a PWA at www.example.com/social and later needed to move it to social.example.com, there was no supported path. Users who had installed your app were stuck — the only option was to manually uninstall, find the new install button, and reinstall.

Changing the start_url without a stable id field created a worse problem: the browser treated the new start_url as a completely different app, creating duplicate installations — the infamous "split app" bug. Users ended up with two icons for the same app, one pointing to the old path and one to the new.

Chrome 150 introduces PWA Origin Migration — a platform feature that solves this problem once and for all. Developers can now transition installed PWAs to a new same-site origin with a single-click update dialog for users. Announced on June 3, 2026, this is one of the most significant PWA platform improvements since the ability to install PWAs on desktop.

What Origin Migration Enables — Real-World Use Cases

The feature unlocks several practical scenarios that were previously impossible or required painful workarounds:

Technical Architecture Freedom

Move your app between subdomains or paths without losing your installed user base:

Fixing the "Split App" Problem

If your PWA's start_url changed at any point without a stable id, existing users ended up with duplicate installations. Origin migration provides a clean way to consolidate these split installations into a single, properly identified app.

Rebranding and Domain Restructuring

Companies rebrand, domains change, and URL structures evolve. With PWA origin migration, you can move your installed PWA to follow your new domain strategy. This is especially valuable during corporate mergers, acquisitions, or strategic pivots where domain changes are inevitable.

Multi-Tenant to Dedicated Domain Migration

If you started with a multi-tenant PWA on a shared subdomain and later need to split it into dedicated domain-based apps per tenant, origin migration makes this possible without losing any installed user base.

How It Works — The Two-Way Handshake

PWA origin migration uses a two-way handshake protocol between the old and new origins. Both sides must explicitly participate — no silent takeovers are possible. Let's walk through each step.

Step 1: The New App Declares the Predecessor

The destination (new) app's web app manifest must include a migrate_from field listing the origin(s) it's migrating from.

// Manifest at https://new-app.example.com/manifest.json
{
  "name": "New App Name",
  "id": "/app/",
  "start_url": "/app/index.html",
  "migrate_from": [
    "https://old-app.example.com/"
  ]
}

Important: The id field in the destination manifest is required. Without it, the browser cannot reliably associate the new installation with the migrated app identity, and you risk creating the very split-app scenario you're trying to fix.

Step 2: The Old Origin Confirms the Migration

The old origin must explicitly authorize the migration by deploying a well-known configuration file. This prevents hostile takeovers — a new site cannot unilaterally hijack an existing app's installation base.

// File at https://old-app.example.com/.well-known/web-app-origin-association
{
  "https://new-app.example.com/app/": {
    "allow_migration": true
  }
}

This file is served from the old origin's .well-known directory, mirroring the pattern used by other web platform features like web-app-origin-association for URL handling. The browser fetches this file during the migration flow to verify authorization.

Step 3: Proactive Signaling (Optional)

To trigger migration proactively — without waiting for users to visit the new site — update the old app's manifest with a migrate_to field pointing to the new origin.

// Updated manifest at https://old-app.example.com/manifest.json
{
  "name": "Old App",
  "start_url": "/",
  "migrate_to": {
    "id": "https://new-app.example.com/app/",
    "install_url": "https://new-app.example.com/app/install"
  }
}

When the browser sees the migrate_to field in the old manifest, it presents the migration option to users proactively — they don't need to navigate to the new site first.

Step 4: Handle Redirects (Optional)

If you've set up redirects from old URLs to the new origin, include an install_url inside the migrate_from field. This tells the browser where to find the old manifest without following redirects.

// Extended migrate_from with install_url
{
  "migrate_from": [
    {
      "id": "https://old-app.example.com/",
      "install_url": "https://old-app.example.com/installwebapp?from=migrate"
    }
  ]
}

Pro tip: Don't skip install_url if your old URLs redirect to the new ones. Without it, redirect chains can prevent the browser from reading the old manifest, and the migration flow may not trigger correctly.

Controlling the User Experience — Suggest vs Force

Chrome 150 supports two migration behavior modes that control how the migration is presented to users:

Suggest Mode (Default)

Behavior: A passive notification appears in the app menu. Users can choose to update, uninstall, or ignore the migration entirely.

When to use: Initial rollouts, A/B testing, gradual migrations where you want to minimize user disruption. Users who are ready to migrate can do so; those who prefer the old experience can stay.

Force Mode

Behavior: A blocking dialog appears on the next app launch. Users must either update or uninstall before they can continue using the app.

{
  "migrate_from": [
    {
      "id": "https://old-app.example.com/",
      "behavior": "force"
    }
  ]
}

When to use: When the old origin is being deprecated, the old domain is expiring, or for enterprise migrations where all users must move to the new origin by a deadline.

Important Restrictions on Forced Migration

Even in force mode, name and icon changes are deferred. After migration completes, the app's display name and icon are updated through the standard app update process — not during the migration dialog. This prevents confusion where a user sees an entirely different app name in the migration confirmation.

Recommendation: Deploy with suggest first, monitor adoption rates via your analytics, then switch to force once you're confident the new origin is stable and users are accustomed to the transition.

Complete End-to-End Migration: 5-File Configuration

Here's a complete reference implementation covering all five files you need to deploy for a full PWA origin migration from old.example.com to new.example.com. Every file is required for a successful migration flow.

File 1: New Origin Manifest

The destination manifest declares the predecessor origin and specifies the migration behavior.

// https://new.example.com/manifest.json
{
  "name": "App Rebranded",
  "short_name": "AppRebrand",
  "id": "/app/",
  "start_url": "/app/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#0f766e",
  "icons": [
    {
      "src": "/icons/icon-192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/icons/icon-512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "migrate_from": [
    {
      "id": "https://old.example.com/",
      "behavior": "suggest"
    }
  ]
}

File 2: Old Origin Well-Known Authorization

Deployed on the old origin to authorize the new one. Without this file, the browser refuses the migration.

// https://old.example.com/.well-known/web-app-origin-association
{
  "https://new.example.com/app/": {
    "allow_migration": true
  }
}

File 3: Old Origin Manifest (Proactive Signal)

Updated on the old origin to proactively push the migration to users who haven't visited the new site yet.

// https://old.example.com/manifest.json
{
  "name": "Original App",
  "id": "/",
  "start_url": "/",
  "display": "standalone",
  "icons": [
    {
      "src": "/icons/icon-192.png",
      "sizes": "192x192",
      "type": "image/png"
    }
  ],
  "migrate_to": {
    "id": "https://new.example.com/app/",
    "install_url": "https://new.example.com/manifest.json"
  }
}

File 4: Service Worker on New Origin

The new origin's service worker handles cache migration and provides fallback behaviour during the transition period.

// https://new.example.com/sw.js
const CACHE_NAME = 'app-v2';

self.addEventListener('install', (event) => {
  // Pre-cache core assets on the new origin
  event.waitUntil(
    caches.open(CACHE_NAME).then((cache) => {
      return cache.addAll([
        '/app/',
        '/app/index.html',
        '/app/styles.css',
        '/app/app.js'
      ]);
    })
  );
});

self.addEventListener('activate', (event) => {
  // Claim clients immediately on new origin
  event.waitUntil(clients.claim());
  // Clean old caches
  event.waitUntil(
    caches.keys().then((keys) => {
      return Promise.all(
        keys.filter((k) => k !== CACHE_NAME)
          .map((k) => caches.delete(k))
      );
    })
  );
});

self.addEventListener('fetch', (event) => {
  // Serve from cache with network fallback
  event.respondWith(
    caches.match(event.request).then((cached) => {
      return cached || fetch(event.request);
    })
  );
});

File 5: Redirect Configuration

Server-level redirects ensure old URLs gracefully forward to the new origin while the migration is in progress. Shown here for NGINX.

# /etc/nginx/sites-available/old.example.com
server {
    listen 443 ssl;
    server_name old.example.com;

    # Redirect all traffic to the new origin
    # The install_url parameter preserves the migration flow
    location / {
        return 301 https://new.example.com/app/$request_uri;
    }

    # Well-known must remain accessible on old origin
    location /.well-known/ {
        alias /var/www/old-app/.well-known/;
        try_files $uri =404;
    }
}

Production tip: Deploy the well-known file and old manifest (Files 2 and 3) on the OLD origin at least 48 hours before publishing the new manifest (File 1). This gives the browser cache time to pick up the authorization and proactive signal, ensuring a smooth migration window.

Service Worker & Data Migration Strategy

While PWA origin migration handles the installation record transfer, application data — IndexedDB, Cache Storage, and service worker state — does NOT automatically migrate. You need a deliberate strategy for data continuity.

Option 1: New Origin Accesses Old Origin's Data

If both origins share the same backend (e.g., same API server), you can simply re-fetch user data from the server. The service worker on the new origin should:

// Service worker on new origin: data migration strategy
const DATA_MIGRATION_KEY = 'data-migration-v1';

self.addEventListener('activate', (event) => {
  // Check if this is a post-migration activation
  event.waitUntil((async () => {
    const migrated = await caches.match(DATA_MIGRATION_KEY);
    if (!migrated) {
      // Fetch user data from the shared backend
      const response = await fetch('/api/user/data', {
        credentials: 'include'
      });
      if (response.ok) {
        const cache = await caches.open('user-data');
        await cache.put('/api/user/data', response);
        await cache.put(DATA_MIGRATION_KEY,
          new Response('migrated', { status: 200 }));
      }
    }
  })());
});

Option 2: Notification-Based Re-Caching

Send a push notification or in-app prompt after migration instructing the client to re-cache critical data. This is the safest approach and mirrors how many major PWAs handle major version updates today.

Data migration tip: Test the full migration flow (install → migrate → launch on new origin) with Chrome Canary before rolling out to production. Pay special attention to IndexedDB databases — their origin-scoped storage does NOT follow the app to the new origin. Plan for a server-side data sync or a user-facing "restore your data" flow on first launch.

Security & Enterprise Considerations

The PWA origin migration feature was designed with security as a first-class concern:

Same-Site Restriction

Only same-site migrations (same eTLD+1) are supported. You can migrate from app.example.com to saas.example.com, but not from example.com to different-domain.com. This restriction prevents cross-organization app hijacking.

Well-Known File Verification

The .well-known/web-app-origin-association file on the old origin serves as the authorization mechanism. Without this file explicitly permitting the migration, the browser will not proceed. This prevents any silent takeover scenario.

Enterprise Policy Controls

For organizations using the WebAppInstallForceList policy to manage PWA installations, there's an important caveat: enterprise-managed apps are blocked from automatic migration. Because enterprise policies are URL/origin-based, a migration could bypass admin controls by moving a managed app to an unmanaged origin. Users will see a banner explaining that policy settings block the migration.

Enterprise administrators should plan migrations through group policy updates, not through the origin migration feature directly.

Migration Checklist — Step-by-Step Guide

Follow this checklist to migrate your PWA seamlessly:

  1. Verify same-site constraint — Confirm old and new origins share the same eTLD+1
  2. Add id field to the destination manifest (required!)
  3. Deploy manifest with migrate_from on the new origin
  4. Create .well-known/web-app-origin-association on the old origin authorizing the migration
  5. Choose behavior: suggest (gradual) or force (mandatory)
  6. (Optional) Deploy migrate_to on the old manifest for proactive signaling
  7. (Optional) Set install_url if old URLs redirect to new ones
  8. Test migration flow in Chrome 150+ beta or Canary
  9. Monitor user adoption — check app update completion rates via your analytics
  10. Deprecate old origin after the migration window closes

Pro tip: For large user bases, deploy with suggest first, monitor adoption for 1-2 weeks, then switch to force. Test every step with Chrome Canary before touching production — it's always ahead of the stable release.

Before vs After Chrome 150

Aspect Before Chrome 150 After Chrome 150
Domain Change Manual uninstall + reinstall One-click migration dialog
User Interruption High — users had to find install button Minimal — familiar update UX
Data Loss Risk Users might not reinstall → churn Automatic transition preserves installs
Security No formal mechanism Two-way handshake with .well-known verification
Enterprise Control Not applicable Policy-controlled via WebAppInstallForceList
Migration Scope Same origin only Same-site (eTLD+1) supported
Developer Effort Manual redirects + user communication 4-step declarative configuration

Browser Support & Future Outlook

PWA origin migration was announced in Chrome 150 beta on June 3, 2026. The stable release is expected approximately 6 weeks later, around July 2026, following Chrome's standard release cycle.

Current support:

As with most new PWA platform features, Safari and Firefox have not yet signaled support. However, because the feature relies on standard web manifest fields and well-known files, it doesn't break anything in non-supporting browsers — the migrate_from and migrate_to fields are simply ignored.

Speculative future: Cross-site migration support (for genuinely related but different domains) would be the next logical evolution, though it introduces significant security and trust challenges. Broader browser adoption will likely follow as the feature matures.

Why this matters for web developers: This is a brand-new feature with essentially zero competition in search results as of June 2026. Being an early publisher on this topic positions your content for long-term organic growth as developers search for migration guides when Chrome 150 reaches stable.

FAQ

What is PWA origin migration in Chrome 150?
PWA origin migration is a new Chrome 150 feature that lets developers seamlessly transition installed Progressive Web Apps to a new same-site origin without requiring users to manually uninstall and reinstall the app. It uses a two-way handshake between the old and new origins, with explicit authorization required from both sides.
Is PWA origin migration secure?
Yes. The feature requires explicit authorization from both origins. The old origin must deploy a .well-known/web-app-origin-association file to confirm the migration. Only same-site (same eTLD+1) migrations are supported, preventing cross-organization hijacking. Enterprise-managed apps installed via the WebAppInstallForceList policy are protected from automatic migration.
What is the difference between suggest and force migration?
Suggest mode (default) shows a passive notification in the app menu — users can update, uninstall, or ignore the migration. Force mode displays a blocking dialog on the next app launch — users must update or uninstall before continuing. Use suggest for gradual rollouts and force when the old origin is being deprecated.
Which browsers support PWA origin migration?
Currently, only Chrome 150+ supports the feature (desktop, Android, and ChromeOS). Other Chromium-based browsers like Edge, Opera, and Samsung Internet are likely to follow since they share the Blink rendering engine. Safari and Firefox have not announced support yet.
What happens to user data like IndexedDB during migration?
PWA origin migration handles the transfer of the app's installation record and identity — not the application data (IndexedDB, cache storage, etc.). Service worker scope and storage may or may not carry over depending on implementation. Developers should plan for data migration separately and test thoroughly with Chrome Canary before rolling out to production.
Can I migrate a PWA from one domain to a completely different domain?
No. PWA origin migration is restricted to same-site migrations only (same eTLD+1). For example, you can migrate from app.example.com to saas.example.com, but not from example.com to different-domain.com. Cross-site migration is not supported for security reasons.
Is the id field required in the destination manifest?
Yes. The id field in the destination web app manifest is required for PWA origin migration. Without it, the browser cannot properly associate the new installation with the migrated app identity, potentially creating a split-app scenario where users end up with duplicate installations.

Need Help with PWA Development?

PWA origin migration is just one piece of the Progressive Web App puzzle. Building a successful PWA requires thoughtful architecture, careful consideration of offline strategies, service worker management, and performance optimization across devices. See my web development services for a full range of what I can build for you.

I'm a full-stack web developer with deep experience building PWAs for businesses in Minsk and worldwide. If you're planning a PWA project, considering origin migration, or need an expert review of your current PWA architecture, reach out to me. I provide free initial consultations.

-->
Contact

Need help with your publishing pipeline?

Whether you're migrating to staged publishing, setting up CI/CD for npm packages, or auditing your supply chain security — I can help. Free consultation.