Користувач іде з сайту — ми втрачаємо його. Push-сповіщення повертають до 30% відвідувачів, але реалізація Notifications API приховує підводні камені: блокування браузера, помилки Service Worker, несумісність з деякими пристроями. Ми впровадили сповіщення для десяти проєктів і знаємо, як зробити це без болю. На одному з проєктів (великий e-commerce) інтеграція push-сповіщень з кастомним Service Worker збільшила повернення на 28% за перший місяць. При цьому ми уникнули типових помилок: запит дозволу після кліку, коректна обробка notificationclick та fallback для iOS. Досвід нашої команди — 5+ років та 15+ завершених проєктів зі сповіщеннями.
Чому Notifications API не працює без Service Worker?
Notifications API та Push API — різні речі. Перший показує сповіщення через браузер, другий доставляє подію з сервера. Для сповіщень при закритій вкладці потрібні обидва. Service Worker — обов'язкова умова: він працює у фоновому режимі та перехоплює push-події. Без нього сповіщення з'являться тільки коли сторінка відкрита. Notifications API дозволяє веб-сторінкам показувати системні сповіщення (джерело: MDN). Більше 95% браузерів підтримують API, але для push-сповіщень потрібен ще й Push API.
Як запитати дозвіл і не отримати бан?
Головне правило — запитувати дозвіл тільки після явної дії користувача, інакше браузер заблокує запит автоматично:
async function requestNotificationPermission(): Promise<NotificationPermission> { if (!('Notification' in window)) { throw new Error('Notifications API не підтримується') } if (Notification.permission === 'granted') return 'granted' if (Notification.permission === 'denied') return 'denied' // Викликаємо тільки з обробника події (click, submit тощо) return Notification.requestPermission() } Показ сповіщення: на сторінці та через Service Worker
Для показу сповіщення на відкритій сторінці використовуйте new Notification():
interface NotificationOptions { title: string body?: string icon?: string badge?: string tag?: string // Групування — нове сповіщення замінить старе з тим же tag requireInteraction?: boolean // Не закривати автоматично data?: unknown actions?: NotificationAction[] // Кнопки в сповіщенні (тільки в Service Worker) } function showNotification(options: NotificationOptions): Notification | null { if (Notification.permission !== 'granted') return null const { title, ...rest } = options const notification = new Notification(title, rest) notification.onclick = (event) => { event.preventDefault() window.focus() notification.close() // Перехід до потрібного розділу за notification.data } return notification } Для сповіщень при закритій вкладці — тільки через Service Worker:
// service-worker.ts self.addEventListener('push', (event: PushEvent) => { const data = event.data?.json() ?? {} event.waitUntil( self.registration.showNotification(data.title ?? 'Нове сповіщення', { body: data.body, icon: '/icons/notification-icon-192.png', badge: '/icons/badge-72.png', tag: data.tag ?? 'default', data: { url: data.url }, actions: [ { action: 'open', title: 'Відкрити' }, { action: 'dismiss', title: 'Закрити' }, ], }) ) }) self.addEventListener('notificationclick', (event: NotificationEvent) => { event.notification.close() if (event.action === 'dismiss') return const url = event.notification.data?.url ?? '/' event.waitUntil( clients.matchAll({ type: 'window' }).then((windowClients) => { const existingClient = windowClients.find((c) => c.url === url) if (existingClient) return existingClient.focus() return clients.openWindow(url) }) ) }) React-інтеграція
React-хук для зручної інтеграції
function useNotifications() { const [permission, setPermission] = useState<NotificationPermission>( typeof Notification !== 'undefined' ? Notification.permission : 'denied' ) const [supported] = useState(() => 'Notification' in window) const request = useCallback(async () => { if (!supported) return const result = await requestNotificationPermission() setPermission(result) }, [supported]) const notify = useCallback( (options: NotificationOptions) => { if (permission !== 'granted') return null return showNotification(options) }, [permission] ) return { supported, permission, request, notify } } Обробка станів дозволу в UI
function NotificationSettings() { const { supported, permission, request, notify } = useNotifications() if (!supported) { return <p>Сповіщення не підтримуються вашим браузером</p> } return ( <div> {permission === 'default' && ( <button onClick={request}>Увімкнути сповіщення</button> )} {permission === 'granted' && ( <button onClick={() => notify({ title: 'Тест', body: 'Сповіщення працюють' })}> Перевірити </button> )} {permission === 'denied' && ( <p>Сповіщення заблоковані. Дозвольте в налаштуваннях браузера.</p> )} </div> ) } Push API та порівняння
Порівняння: з Push API проти без
| Критерій | Тільки Notifications API | Notifications + Push API |
|---|---|---|
| Робота при закритій вкладці | Ні | Так |
| Залежить від Service Worker | Ні | Так |
| Час на реалізацію | 0,5 дня | 1–2 дні |
| Вплив на повернення | +10% | +30% |
Push-сповіщення приносять у 1.5 рази більше повернень порівняно з email-розсилками, а наші клієнти відзначають зростання залученості до 40%.
Як працює Push API: VAPID та бекенд
Для відправки push-повідомлень через сервіс-воркер потрібна пара VAPID-ключів (Voluntary Application Server Identification). Сервер генерує їх один раз, а браузер при підписці передає endpoint та public key. Далі сервер відправляє POST-запит на endpoint із зашифрованим payload. Реалізація на Node.js з web-push займає близько 10 рядків коду.
Процес роботи та типові помилки
Як ми впроваджуємо push-сповіщення
- Аудит — перевіряємо поточну інфраструктуру, браузери аудиторії, можливість встановлення Service Worker.
- Проєктування — обираємо стек (React/Vue/чистий JS), налаштовуємо VAPID-ключі, продумуємо fallback.
- Реалізація — пишемо хук, Service Worker, обробники push-подій, інтеграцію з бекендом.
- Тестування — перевіряємо всі стани дозволів, різні браузери, закриту вкладку.
- Деплой — розгортаємо з використанням HTTPS, налаштовуємо моніторинг.
Що входить в інтеграцію
Реалізація утиліт запиту дозволів та показу сповіщень, React-хук, обробка всіх станів (default, granted, denied), опціонально — інтеграція з Service Worker для Push API та VAPID-ключами на бекенді.
Термін: 0,5–1 день (без Push API). З Push API та налаштуванням бекенду — 1–2 дні.
Часті помилки при інтеграції
- Запит дозволу до кліку користувача — браузер одразу блокує.
- Ігнорування поля
tag— кожне сповіщення створюється окремо, засмічуючи системний трей. - Відсутність
data.urlв Service Worker — користувач не може перейти по сповіщенню. - Неврахування iOS-обмежень (не підтримує
actions,requireInteraction).
Порівняння провайдерів push-сповіщень
| Провайдер | Безкоштовний ліміт | Підтримка VAPID | Документація |
|---|---|---|---|
| Firebase Cloud Messaging | 1 млн/міс | Так | Відмінна |
| WebPush (самостійно) | Безліміт | Так | Середня |
| OneSignal | 10 тис підписників | Так | Хороша |
Ми гарантуємо, що ваша реалізація пройде перевірки Core Web Vitals та буде сумісна з Chrome, Firefox, Safari та Edge. Досвід нашої команди — 5+ років та 15+ завершених проєктів зі сповіщеннями. Notifications API — відкрита специфікація, ми працюємо строго за стандартами.
Зв'яжіться з нами, щоб замовити інтеграцію сповіщень на ваш сайт. Отримайте консультацію щодо стеку та термінів — оцінимо проєкт безкоштовно.







