How to Set Up Web Push Notifications on Your Website (2026 Guide)
A practical 2026 step-by-step guide to web push: service worker, VAPID keys, an opt-in prompt that converts, and sending your first notification.
Web push notifications let you re-engage visitors right in their browser โ no app store, no email address, no extra install. They reach subscribers on the desktop or mobile home screen even when your tab is closed. This guide walks through the full setup in 2026: a service worker, VAPID keys, a respectful opt-in prompt, and your first send.
If you want to skip the boilerplate, a hosted tool like relaybell handles the keys, delivery, and dashboards so you can be live in minutes. But it helps to understand each moving part first.
What you need before you start
Web push runs on a few open web standards. Make sure you have:
- HTTPS โ service workers and the Push API only work on secure origins (
localhostis exempt for testing). - A service worker file served from your domain.
- VAPID keys โ a public/private key pair that identifies your server to push services.
- A push service โ Chrome, Firefox, Edge, and Safari each route through their own endpoint automatically; you don't choose it.
Browser support is broad in 2026: Chromium browsers, Firefox, and Safari (including iOS for installed/home-screen web apps) all support the Push API.
Step 1: Register a service worker
The service worker is a background script that receives push events even when your site isn't open. Create sw.js at your site root and register it from your main page:
if ('serviceWorker' in navigator && 'PushManager' in window) {
navigator.serviceWorker.register('/sw.js');
}
Inside sw.js, listen for incoming pushes and clicks:
self.addEventListener('push', (event) => {
const data = event.data.json();
event.waitUntil(
self.registration.showNotification(data.title, {
body: data.body,
icon: '/icon.png',
data: { url: data.url }
})
);
});
self.addEventListener('notificationclick', (event) => {
event.notification.close();
event.waitUntil(clients.openWindow(event.notification.data.url));
});
Step 2: Generate VAPID keys
VAPID (Voluntary Application Server Identification) proves to the push service that messages come from you. You generate the key pair once. The public key goes into your front-end subscription request; the private key stays on your server and signs each send.
You can generate keys with the web-push library (npx web-push generate-vapid-keys) or let your provider create them for you. Never expose the private key in client code.
Step 3: Build an opt-in prompt that converts
This is where most sites lose subscribers. Firing the native browser permission dialog the instant someone lands almost guarantees a "Block" โ and a block is permanent.
A better pattern:
- Ask in context. Trigger the prompt after a useful action โ reading an article, adding to cart, checking an order.
- Use a soft pre-prompt. Show your own branded "Get notified about X?" banner first. Only call the native dialog when the user says yes, so a hesitation never burns the real permission.
- State the value. "Get notified when your order ships" beats "Allow notifications."
When the user accepts, subscribe them:
const reg = await navigator.serviceWorker.ready;
const sub = await reg.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: '<YOUR_PUBLIC_VAPID_KEY>'
});
await fetch('/api/save-subscription', {
method: 'POST',
body: JSON.stringify(sub)
});
Send that subscription object to your backend and store it. It's the address you'll push to.
Step 4: Send your first notification
On the server, sign and deliver the payload with your private VAPID key:
const webpush = require('web-push');
webpush.setVapidDetails('mailto:you@site.com', PUBLIC_KEY, PRIVATE_KEY);
webpush.sendNotification(subscription, JSON.stringify({
title: 'Welcome aboard',
body: 'Thanks for subscribing!',
url: 'https://yoursite.com/welcome'
}));
The push service queues and delivers it; your service worker's push listener renders it. Handle 410 Gone responses by deleting stale subscriptions so your list stays clean.
Step 5: Segment and measure
Sending the same message to everyone wastes a hard-won channel. Tag subscribers by behavior โ pages viewed, location, purchase history โ and target accordingly.
Typical web push benchmarks to aim for:
- Opt-in rate often lands in the low double digits when you use a contextual pre-prompt, versus low single digits for an instant native ask.
- Click-through rates commonly run several times higher than email, frequently in the mid-to-high single-digit percentages for well-segmented sends.
These are typical ranges, not guarantees โ your audience and message relevance drive the real numbers. Track delivery, CTR, and unsubscribe trends per segment and iterate.
Skip the plumbing
You can wire all of this by hand, or hand the keys, storage, segmentation, and analytics to a service. relaybell gives you a hosted setup that's free to deliver and live in minutes, so you spend time on messaging instead of infrastructure.
Ready to try web push? Get started with relaybell โ free to deliver, live in minutes.