Реалізація встановлення PWA на пристрій (Add to Home Screen)

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.
Розробка та обслуговування будь-яких видів сайтів:
Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Реалізація встановлення PWA на пристрій (Add to Home Screen)
Середня
від 1 робочого дня до 3 робочих днів
Часті питання
Наші компетенції:
Етапи розробки
Останні роботи
  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Реалізація установки PWA на пристрій (Add to Home Screen)

Add to Home Screen — механізм, що дозволяє користувачу встановити веб-приложення на екран пристрою без магазину приложень. Це не просто ярлик: встановлене PWA запускається без браузерної рядки, отримує окрему іконку, з'являється у списку приложень та, на Android, в установщику. Різниця в утриманні користувачів вимірюється: в середньому CTR у встановлених PWA на 50–70% вищий, ніж у звичайних закладок.

Що потрібно для появи промпта

Браузер показує системний промпт установки тільки при одночасному виконанні кількох умов:

  • Сайт працює на HTTPS (localhost — виключення при розробці)
  • Зареєстрований Service Worker, який перехоплює мінімум fetch-подію
  • Присутній manifest.json з обов'язковими полями: name, short_name, start_url, display, та іконками 192px та 512px
  • Користувач провів на сайті достатньо часу (Chrome застосовує власну евристику, точні пороги не задокументовані публічно)

На iOS немає жодного автоматичного промпта — тільки ручне додавання через «Поділитися → На екран Домой». Це принципіальне обмеження Safari, яке ніяк не обійти.

Перехват подій beforeinstallprompt

Chrome та Edge генерують подію beforeinstallprompt до того, як показати системний діалог. Потрібно перехопити та показати власний UI:

let deferredPrompt = null;

window.addEventListener('beforeinstallprompt', (e) => {
  // Запобігаємо автоматичному показу
  e.preventDefault();
  deferredPrompt = e;

  // Показуємо власну кнопку установки
  showInstallBanner();
});

async function triggerInstall() {
  if (!deferredPrompt) return;

  deferredPrompt.prompt();

  const { outcome } = await deferredPrompt.userChoice;

  // Логуємо результат
  gtag('event', 'pwa_install', {
    event_category: 'PWA',
    event_label: outcome, // 'accepted' | 'dismissed'
  });

  deferredPrompt = null;
  hideInstallBanner();
}

window.addEventListener('appinstalled', () => {
  // Приложення встановлено — скриваємо баннери
  hideInstallBanner();
  deferredPrompt = null;
});

Важливо: prompt() можна викликати тільки один раз. Після виклику deferredPrompt стає невалідним. Якщо користувач відхилив — наступного события beforeinstallprompt доведеться чекати до кількох тижнів (Chrome запропонує не раніше ніж через 90 днів після відмови).

Визначення контексту запуску

Потрібно розуміти, у якому режимі запущено приложення:

function getDisplayMode() {
  if (window.matchMedia('(display-mode: standalone)').matches) {
    return 'standalone';
  }
  if (window.matchMedia('(display-mode: fullscreen)').matches) {
    return 'fullscreen';
  }
  if (window.navigator.standalone === true) {
    // iOS Safari
    return 'standalone-ios';
  }
  return 'browser';
}

// Перевіримо при завантаженні
const mode = getDisplayMode();
if (mode === 'browser') {
  // Можемо показувати підказку про установку
}

// Слухаємо зміни
window.matchMedia('(display-mode: standalone)').addEventListener('change', (e) => {
  if (e.matches) {
    console.log('App is now in standalone mode');
  }
});

Баннер для iOS

Safari на iOS не підтримує beforeinstallprompt. Приходиться показувати власну інструкцію:

function shouldShowIOSPrompt() {
  const isIOS = /iphone|ipad|ipod/i.test(navigator.userAgent);
  const isInStandaloneMode = window.navigator.standalone === true;
  const hasSeenPrompt = localStorage.getItem('ios-install-prompt-shown');

  return isIOS && !isInStandaloneMode && !hasSeenPrompt;
}

if (shouldShowIOSPrompt()) {
  showIOSInstructionBanner();
  localStorage.setItem('ios-install-prompt-shown', 'true');
}

Баннер повинен показувати іконку кнопки «Поділитися» (може різнитися між версіями iOS) та текст «Натисніть Share → Додати на екран Домой». Іконку краще брати в форматі SVG, що збігається з реальною системною іконкою.

Манівфест

Мінімальний робочий manifest.json:

{
  "name": "Назва приложення",
  "short_name": "Приложення",
  "description": "Описання для магазину",
  "start_url": "/?source=pwa",
  "scope": "/",
  "display": "standalone",
  "orientation": "any",
  "background_color": "#ffffff",
  "theme_color": "#1a73e8",
  "icons": [
    {
      "src": "/icons/icon-192.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "/icons/icon-512.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any maskable"
    }
  ],
  "screenshots": [
    {
      "src": "/screenshots/desktop.png",
      "sizes": "1280x720",
      "type": "image/png",
      "form_factor": "wide"
    },
    {
      "src": "/screenshots/mobile.png",
      "sizes": "390x844",
      "type": "image/png",
      "form_factor": "narrow"
    }
  ]
}

purpose: "maskable" важен для Android — система може обрізати іконку під різні форми. Іконка повинна мати безпечну зону: контент не ближче ніж на 10% від крайів.

screenshots з'являються в діалозі установки в Chrome 108+ — робить промпт більш переконливим.

Аналітика воронки установки

Без аналітики непонятно, де користувачі відваливаються:

const INSTALL_FUNNEL = {
  BANNER_SHOWN: 'install_banner_shown',
  BANNER_CLICKED: 'install_banner_clicked',
  PROMPT_SHOWN: 'install_prompt_shown',
  PROMPT_ACCEPTED: 'install_prompt_accepted',
  PROMPT_DISMISSED: 'install_prompt_dismissed',
  APP_INSTALLED: 'app_installed',
};

function trackInstallStep(step, params = {}) {
  gtag('event', step, {
    event_category: 'pwa_install_funnel',
    ...params,
  });
}

Стандартна воронка: показ баннера → клік → показ системного промпта → прийняття. Типовий конверт промпта — 20–40% у мотивованої аудиторії.

Часові рамки реалізації

  • Манівфест + базовий Service Worker + перехват події: 1 день
  • Кастомний баннер установки з аналітикою: 1 день
  • Підтримка iOS (інструкція + визначення режиму): 0.5 дня
  • Іконки в форматах maskable + адаптація дизайну: 0.5 дня

Всього: 2–3 дні від нуля до повної реалізації з аналітикою.