Setup Push Notifications

Push notifications are one of the most powerful tools for re-engaging users and driving conversions in modern web applications. With proper implementation, they can increase user retention by up to 88% and boost click-through rates significantly compared to traditional email marketing.
This comprehensive guide covers everything from basic browser notification APIs to advanced server-side integration, subscription management, and notification optimization strategies. Whether you're building a simple blog or a complex web application, you'll learn to implement push notifications that users actually want to receive.
Understanding Web Push Notifications
Web push notifications are messages sent from a server to a user's device through the browser, even when the website isn't actively open. They work through service workers and the Push API to deliver timely, relevant information.
Browser-Based
Works across all modern browsers without requiring app installation or app store approval.
Real-time
Instant delivery to users' devices as soon as they're sent from your server.
Permission-Based
Users explicitly opt-in, ensuring notifications reach engaged audiences.
Push Notification Architecture
Client-Side Components
- Permission Request Interface
- Service Worker Registration
- Subscription Management
- Notification Event Handlers
Server-Side Components
- VAPID Key Generation
- Subscription Storage
- Push Service Integration
- Notification Sending Logic
Browser Support & Compatibility
| Browser | Desktop Support | Mobile Support | Key Limitations |
|---|---|---|---|
| Chrome | Full Support | Full Support | None |
| Firefox | Full Support | Full Support | None |
| Safari | Limited | No Support | macOS only, iOS unsupported |
| Edge | Full Support | Full Support | None |
| Opera | Full Support | Full Support | None |
Step-by-Step Implementation Guide
Check Browser Support
Detect if the browser supports push notifications and service workers.
Request Permission
Ask user for notification permission with proper UX timing.
Register Service Worker
Set up service worker to handle push events and notifications.
Generate VAPID Keys
Create application server keys for secure communication.
Subscribe User
Create push subscription and send to your server.
Send Notifications
Implement server-side logic to send push notifications.
Frontend Implementation
Feature Detection & Permission Request
First, check if the browser supports push notifications and request permission from the user:
functionisPushSupported() {
return'serviceWorker'innavigator &&
'PushManager'inwindow &&
'Notification'inwindow;
}
// Request notification permission
async functionrequestNotificationPermission() {
if(!isPushSupported()) {
console.warn('Push notifications not supported');
return'unsupported';
}
// Check current permission status
if(Notification.permission ==='granted') {
return'granted';
}
// Request permission if not already decided
if(Notification.permission ==='default') {
constpermission =awaitNotification.requestPermission();
returnpermission;
}
returnNotification.permission;
}
Service Worker Registration
Register a service worker to handle push events and display notifications:
async functionregisterServiceWorker() {
try{
constregistration =awaitnavigator.serviceWorker
.register('/sw.js');
console.log('Service Worker registered:', registration);
returnregistration;
}catch(error) {
console.error('Service Worker registration failed:', error);
throwerror;
}
}
// Service Worker file (sw.js)
self.addEventListener('push',function(event) {
constoptions = {
body: event.data ? event.data.text() :'Default message',
icon:'/icon-192x192.png',
badge:'/badge-72x72.png',
vibrate: [100, 50, 100],
data: {
dateOfArrival: Date.now(),
primaryKey: 1
}
};
event.waitUntil(
self.registration.showNotification('Push Notification', options)
);
});
User Subscription Management
Create and manage push subscriptions for users:
constvapidPublicKey ='your-vapid-public-key-here';
// Convert VAPID key to Uint8Array
functionurlBase64ToUint8Array(base64String) {
constpadding ='='.repeat((4 - base64String.length % 4) % 4);
constbase64 = (base64String + padding)
.replace(/\-/g,'+')
.replace(/_/g,'/');
constrawData = window.atob(base64);
constoutputArray =newUint8Array(rawData.length);
for(leti = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
returnoutputArray;
}
Advanced Notification Features
Action Buttons
Add interactive buttons to notifications for direct user actions.
constoptions = {
body:'You have a new message',
actions: [
{
action:'reply',
title:'Reply',
icon:'/reply-icon.png'
},
{
action:'view',
title:'View'
}
]
};
Rich Media
Include images, custom icons, and visual elements in notifications.
constoptions = {
body:'Check out this article',
icon:'/app-icon.png',
image:'/article-preview.jpg',
badge:'/badge-icon.png',
vibrate: [200, 100, 200],
tag:'article-notification'
};
Push Notification Best Practices
Do's
- Request permission at the right moment
- Provide clear value proposition
- Personalize notification content
- Use proper timing and frequency
- Include relevant action buttons
- Test across different devices
- Handle subscription failures gracefully
Don'ts
- Ask for permission immediately on page load
- Send notifications too frequently
- Use generic, irrelevant messages
- Ignore user preferences and settings
- Send notifications at inappropriate times
- Forget to handle unsubscribe requests
- Neglect proper error handling
Backend Implementation
VAPID Keys Generation
Generate VAPID (Voluntary Application Server Identification) keys for secure communication:
npm install web-push
// Generate VAPID keys (Node.js)
constwebpush =require('web-push');
// Generate keys once and store securely
constvapidKeys = webpush.generateVAPIDKeys();
console.log('Public Key:', vapidKeys.publicKey);
console.log('Private Key:', vapidKeys.privateKey);
// Set VAPID details
webpush.setVapidDetails(
'mailto:your-email@example.com',
vapidKeys.publicKey,
vapidKeys.privateKey
);
Subscription Storage & Management
Store and manage user subscriptions on your server:
constexpress =require('express');
constapp =express();
app.use(express.json());
// Store subscription
app.post('/api/subscribe',async(req, res) => {
try{
constsubscription = req.body;
// Validate subscription object
if(!subscription || !subscription.endpoint) {
returnres.status(400).json({
error:'Invalid subscription object'
});
}
// Save to database
awaitsaveSubscriptionToDatabase(subscription);
res.status(201).json({ success:true});
}catch(error) {
console.error('Error saving subscription:', error);
res.status(500).json({ error:'Server error'});
}
});
Sending Push Notifications
Implement the server logic to send push notifications to subscribed users:
async functionsendNotificationToUser(subscription, payload) {
try{
constresult =awaitwebpush.sendNotification(
subscription,
JSON.stringify(payload)
);
console.log('Notification sent successfully', result);
returnresult;
}catch(error) {
console.error('Error sending notification:', error);
// Handle expired/invalid subscriptions
if(error.statusCode === 410) {
awaitremoveInvalidSubscription(subscription);
}
throwerror;
}
}
Testing & Debugging Push Notifications
Chrome DevTools
Use Application tab > Service Workers to test push events manually.
Built-inFirefox DevTools
Console and Network tabs for debugging push subscription issues.
Built-inMobile Testing
Test on actual mobile devices for real-world notification behavior.
ManualDesktop Testing
Verify notification appearance and behavior across desktop browsers.
EasyWeb Push Testing
Online tool for testing push notifications without backend setup.
FreePostman/Insomnia
Test push service API endpoints directly with HTTP requests.
Recommendedcurl Commands
Command-line testing for quick push notification validation.
CLILighthouse
Audit push notification implementation as part of PWA checks.
GoogleCommon Issues & Solutions
Permission Denied
User has blocked notifications. Provide clear re-enable instructions.
Check: Notification.permission === 'denied'Service Worker Registration Failed
HTTPS required, check file path and service worker syntax.
Check: navigator.serviceWorker.register() errorsSubscription Creation Failed
Invalid VAPID keys or push service unavailable.
Check: pushManager.subscribe() errorsFrequently Asked Questions
Do push notifications work on iOS Safari?
What happens when a user's subscription expires?
How many notifications can I send per day?
Can I send push notifications without a server?
How do I handle users who deny notification permission?
What's the difference between local and push notifications?
Got an Idea or Question?
Looking to build, enhance, or fix your website? At Mirage Code, our experienced team can turn your vision into reality. Let's bring your ideas to life
No commitment required. See exactly what's holding your website back.
About Mirage Code
Mirage Code specializes in building scalable, high-converting websites for businesses of all sizes. Our team combines technical expertise with conversion optimization strategies to deliver websites that not only look great but also drive real business results.
Ready to discuss your project? Contact us today for a free consultation and discover how we can transform your website into a powerful conversion machine.
(2) Comments
Mohamed Nakhlawy
Aug 26, 2025 at 11:37 AMsome text here
1 Replies