Полный разбор новой функции Chrome 150 для миграции origin PWA — two-way handshake, режимы suggest и force, вопросы безопасности и пошаговый чеклист миграции для разработчиков.
С момента появления Progressive Web Apps одним из самых болезненных ограничений была
жёсткая привязка идентичности PWA к его веб-ориджину. Если вы развернули
PWA на www.example.com/social, а затем понадобилось перенести его на
social.example.com, то поддерживаемого пути не существовало. Пользователи,
установившие ваше приложение, оказывались в тупике — единственным выходом было вручную
удалить приложение, найти новую кнопку установки и переустановить.
Изменение start_url без стабильного поля id создавало ещё
более серьёзную проблему: браузер воспринимал новый start_url как совершенно другое
приложение, создавая дублирующиеся установки — пресловутый баг
«раздвоения приложения». Пользователи получали две иконки одного и того же приложения,
одна из которых вела на старый путь, а другая на новый.
Chrome 150 представляет миграцию origin PWA — платформенную функцию, которая раз и навсегда решает эту проблему. Разработчики теперь могут переносить установленные PWA на новый origin в пределах одного сайта через диалог обновления в один клик. Анонсированная 3 июня 2026 года, это одно из самых значительных улучшений платформы PWA со времён появления возможности устанавливать PWA на десктоп.
Функция открывает несколько практических сценариев, которые ранее были невозможны или требовали болезненных обходных путей:
Перемещайте приложение между поддоменами или путями без потери установленной пользовательской базы:
app.example.com → saas.example.com (ребрендинг продукта)example.com/old-app → new-app.example.com (выделение продукта)example.com/user → user.example.com (выделенный поддомен для функции)
Если start_url вашего PWA когда-либо менялся без стабильного id,
существующие пользователи получали дублирующиеся установки. Миграция origin предоставляет
чистый способ консолидировать эти разделённые установки в единое, правильно идентифицированное
приложение.
Компании проводят ребрендинг, домены меняются, структура URL эволюционирует. С миграцией origin PWA вы можете переместить установленное PWA вслед за новой доменной стратегией. Это особенно ценно при корпоративных слияниях, поглощениях или стратегических разворотах, где смена доменов неизбежна.
Если вы начинали с мультитенантного PWA на общем поддомене, а затем потребовалось разделить его на отдельные доменные приложения для каждого клиента, миграция origin делает это возможным без потери установленной пользовательской базы.
Миграция origin PWA использует протокол двухстороннего рукопожатия между старым и новым ориджинами. Обе стороны должны явно участвовать — бесшумные захваты невозможны. Разберём каждый шаг.
Манифест целевого (нового) приложения должен включать поле migrate_from,
перечисляющее ориджины, с которых происходит миграция.
// Манифест на 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/"
]
}
Важно: Поле id в целевом манифесте обязательно.
Без него браузер не сможет надёжно связать новую установку с идентификатором мигрированного
приложения, и вы рискуете воссоздать тот самый сценарий раздвоения приложения, который
пытаетесь исправить.
Старый origin должен явно авторизовать миграцию, развернув well-known конфигурационный файл. Это предотвращает враждебные захваты — новый сайт не может в одностороннем порядке перехватить установочную базу существующего приложения.
// Файл на https://old-app.example.com/.well-known/web-app-origin-association
{
"https://new-app.example.com/app/": {
"allow_migration": true
}
}
Этот файл располагается в директории .well-known старого origin,
повторяя шаблон, используемый другими функциями веб-платформы, такими как
web-app-origin-association для обработки URL. Браузер загружает этот файл
в процессе миграции для проверки авторизации.
Чтобы инициировать миграцию упреждающе — не дожидаясь, пока пользователи посетят новый
сайт — обновите манифест старого приложения, добавив поле
migrate_to, указывающее на новый origin.
// Обновлённый манифест на 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"
}
}
Когда браузер видит поле migrate_to в старом манифесте, он упреждающе
предлагает пользователю вариант миграции — ему не нужно сначала переходить на новый сайт.
Если вы настроили перенаправления со старых URL на новый origin, включите
install_url внутрь поля migrate_from. Это сообщает браузеру,
где найти старый манифест, не следуя по цепочке перенаправлений.
// Расширенный migrate_from с install_url
{
"migrate_from": [
{
"id": "https://old-app.example.com/",
"install_url": "https://old-app.example.com/installwebapp?from=migrate"
}
]
}
Совет: Не пропускайте install_url, если ваши старые URL перенаправляют на новые. Без него цепочки редиректов могут помешать браузеру прочитать старый манифест, и механизм миграции может не сработать корректно.
Chrome 150 поддерживает два режима поведения миграции, определяющих, как миграция представляется пользователям:
Поведение: Пассивное уведомление в меню приложения. Пользователи могут обновиться, удалить приложение или полностью проигнорировать миграцию.
Когда использовать: Первоначальные развёртывания, A/B-тестирование, постепенные миграции с минимальным disruption для пользователей. Те, кто готов мигрировать, могут это сделать; те, кто предпочитает старый опыт, могут остаться.
Поведение: Блокирующий диалог при следующем запуске приложения. Пользователи должны либо обновиться, либо удалить приложение, прежде чем продолжить использование.
{
"migrate_from": [
{
"id": "https://old-app.example.com/",
"behavior": "force"
}
]
}
Когда использовать: Когда старый origin выводится из эксплуатации, срок действия старого домена истекает, или для корпоративных миграций, где все пользователи должны перейти на новый origin к определённому сроку.
Даже в режиме force изменение названия и иконки откладывается.
После завершения миграции отображаемое имя и иконка приложения обновляются через
стандартный процесс обновления приложения, а не в диалоге миграции. Это предотвращает
путаницу, когда пользователь видит совершенно другое название приложения в подтверждении
миграции.
Рекомендация: Сначала разверните в режиме suggest,
отслеживайте показатели принятия через вашу аналитику, затем переключайтесь на
force, когда убедитесь в стабильности нового origin и привыкании
пользователей к переходу.
Полный эталонный пример со всеми пятью файлами для миграции PWA с old.example.com
на new.example.com. Каждый файл необходим для успешного процесса миграции.
Целевой манифест объявляет origin-предшественник и задаёт режим миграции.
// 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"
}
]
}
Развёртывается на старом origin для авторизации нового. Без этого файла браузер отказывает в миграции.
// https://old.example.com/.well-known/web-app-origin-association
{
"https://new.example.com/app/": {
"allow_migration": true
}
}
Обновлённый манифест на старом origin для упреждающего уведомления пользователей, которые ещё не посетили новый сайт.
// 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"
}
}
Service Worker нового origin обрабатывает миграцию кеша и обеспечивает резервное поведение в переходный период.
// https://new.example.com/sw.js
const CACHE_NAME = 'app-v2';
self.addEventListener('install', (event) => {
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) => {
event.waitUntil(clients.claim());
event.waitUntil(
caches.keys().then((keys) => {
return Promise.all(
keys.filter((k) => k !== CACHE_NAME)
.map((k) => caches.delete(k))
);
})
);
});
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((cached) => {
return cached || fetch(event.request);
})
);
});
Серверные редиректы обеспечивают graceful перенаправление старых URL на новый origin во время миграции. Пример для NGINX.
# /etc/nginx/sites-available/old.example.com
server {
listen 443 ssl;
server_name old.example.com;
location / {
return 301 https://new.example.com/app/$request_uri;
}
location /.well-known/ {
alias /var/www/old-app/.well-known/;
try_files $uri =404;
}
}
Совет для продакшна: Разверните well-known файл и старый манифест (Файлы 2 и 3) на СТАРОМ origin минимум за 48 часов до публикации нового манифеста (Файл 1). Это даёт кешу браузера время для загрузки авторизации и упреждающего сигнала.
Миграция origin PWA обрабатывает перенос записи об установке приложения, но данные приложения — IndexedDB, Cache Storage и состояние service worker — НЕ мигрируются автоматически. Необходима продуманная стратегия обеспечения непрерывности данных.
Если оба origin используют один и тот же бэкенд, service worker на новом origin может просто заново загрузить данные пользователя:
// Service worker на новом origin: стратегия миграции данных
const DATA_MIGRATION_KEY = 'data-migration-v1';
self.addEventListener('activate', (event) => {
event.waitUntil((async () => {
const migrated = await caches.match(DATA_MIGRATION_KEY);
if (!migrated) {
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 }));
}
}
})());
});
Отправьте push-уведомление или внутриприложенческую подсказку после миграции, предписывающую клиенту перезагрузить критически важные данные.
Совет по миграции данных: Протестируйте полный процесс миграции (установка → миграция → запуск на новом origin) с Chrome Canary перед развёртыванием в продакшн. Обратите особое внимание на базы IndexedDB — их хранилище, привязанное к origin, НЕ переходит на новый origin вместе с приложением. Планируйте серверную синхронизацию данных или пользовательский процесс восстановления данных при первом запуске.
Функция миграции origin PWA разработана с учётом безопасности как приоритета первого уровня:
Поддерживаются только миграции в пределах одного сайта (same eTLD+1).
Вы можете перенести приложение с app.example.com на saas.example.com,
но не с example.com на different-domain.com. Это ограничение
предотвращает перехват приложений между разными организациями.
Файл .well-known/web-app-origin-association на старом origin служит
механизмом авторизации. Без явного разрешения миграции в этом файле браузер не
продолжит процесс. Это предотвращает любой сценарий бесшумного захвата.
Для организаций, использующих политику WebAppInstallForceList для управления установками PWA, существует важное ограничение: корпоративные приложения блокируются от автоматической миграции. Поскольку корпоративные политики привязаны к URL/origin, миграция может обойти контроль администратора, переместив управляемое приложение на неуправляемый origin. Пользователи увидят баннер с объяснением, что настройки политики блокируют миграцию.
Корпоративным администраторам следует планировать миграции через обновление групповых политик, а не через функцию миграции origin напрямую.
Следуйте этому чеклисту для бесшовной миграции вашего PWA:
id в целевой манифест (обязательно!)migrate_from на новом origin.well-known/web-app-origin-association на старом origin, авторизующий миграциюsuggest (постепенная) или force (обязательная)migrate_to в старом манифесте для упреждающего оповещенияinstall_url если старые URL перенаправляют на новыеСовет: Для большой пользовательской базы разворачивайте сначала в режиме suggest, отслеживайте принятие в течение 1-2 недель, затем переключайтесь на force. Тестируйте каждый шаг с Chrome Canary перед выходом в продакшн.
| Аспект | До Chrome 150 | После Chrome 150 |
|---|---|---|
| Смена домена | Ручное удаление + переустановка | Миграция в один клик |
| Прерывание пользователя | Высокое — нужно найти кнопку установки | Минимальное — знакомый UX обновления |
| Риск потери данных | Пользователи могут не переустановить → отток | Автоматический переход сохраняет установки |
| Безопасность | Нет формального механизма | Двухстороннее рукопожатие с верификацией .well-known |
| Корпоративный контроль | Не применимо | Управляется политиками через WebAppInstallForceList |
| Область миграции | Только один origin | Один сайт (eTLD+1) |
| Усилия разработчика | Ручные редиректы + коммуникация с пользователями | Декларативная конфигурация из 4 шагов |
Миграция origin PWA была анонсирована в Chrome 150 beta 3 июня 2026 года. Стабильный релиз ожидается примерно через 6 недель, около июля 2026 года, следуя стандартному циклу релизов Chrome.
Текущая поддержка:
Как и в случае с большинством новых функций платформы PWA, Safari и Firefox пока
не сообщили о поддержке. Однако поскольку функция использует стандартные поля манифеста
и well-known файлы, она ничего не ломает в неподдерживающих браузерах — поля
migrate_from и migrate_to просто игнорируются.
Перспективы: Поддержка кросс-сайтовой миграции (для действительно связанных, но разных доменов) была бы следующим логическим шагом эволюции, хотя это создаёт значительные проблемы безопасности и доверия. Расширение поддержки браузеров, вероятно, последует по мере созревания функции.
.well-known/web-app-origin-association для одобрения миграции. Поддерживаются только миграции в пределах одного сайта (same eTLD+1), что предотвращает перехват приложений между разными организациями. Корпоративные приложения, установленные через политику WebAppInstallForceList, защищены от автоматической миграции.app.example.com на saas.example.com, но не с example.com на different-domain.com. Кросс-сайтовая миграция не поддерживается по соображениям безопасности.id в манифесте целевого приложения обязательно для миграции origin PWA. Без него браузер не сможет правильно ассоциировать новую установку с идентификатором мигрированного приложения, что может привести к появлению дублирующихся установок.Миграция origin — лишь одна часть пазла Progressive Web Apps. Создание успешного PWA требует продуманной архитектуры, тщательного подхода к офлайн-стратегиям, управления сервис-воркерами и оптимизации производительности на разных устройствах. Посмотрите мои услуги веб-разработчика — от PWA до полноценных веб-приложений.
Я — full-stack веб-разработчик с глубоким опытом создания PWA для бизнеса в Минске и по всему миру. Если вы планируете PWA-проект, рассматриваете миграцию origin или нуждаетесь в экспертной оценке текущей PWA-архитектуры, свяжитесь со мной. Я предоставляю бесплатные первичные консультации.
Миграция на staged publishing, настройка CI/CD для npm-пакетов или аудит безопасности цепочки поставок — я помогу. Бесплатная консультация.