How Do I Add Push Notifications to My PWA?
A delivery driver opens a logistics company's PWA on their phone to check their route for the day—but here's what makes it work brilliantly: they get instant push notifications when new parcels are added to their schedule, when delivery addresses change, or when a customer leaves special instructions. They don't need to keep refreshing the app or checking back constantly. The notifications just appear, same as they would from a native app. That's the power of push notifications in progressive web apps, and its one of the biggest reasons why PWAs have become such a serious option for businesses that need real-time engagement with their users.
Now I'll be honest, when PWAs first started gaining traction I was a bit skeptical about whether web push could really match what native apps offered. But the Web Push API has matured to the point where the experience is basically identical for users—they get notifications on their lock screen, they can tap to open your app, and the whole thing feels just like a native mobile experience. The technical implementation is different under the hood (it uses service workers instead of platform-specific notification systems) but your users won't know or care about that.
Adding push notifications to your PWA isn't just about sending messages; its about creating a communication channel that brings users back to your app when it matters most.
The thing is, push notifications are probably the single most effective tool for keeping users engaged with your app over time. I've seen apps with brilliant functionality fail because they couldn't remind users to come back. And I've seen fairly simple apps succeed because they mastered the art of timely, relevant notifications. Whether you're building a delivery app, an e-commerce platform, or a content site, understanding how to implement push notifications properly will make a massive difference to your engagement rates and user retention.
Understanding Push Notifications in PWAs
Right, so lets start with what push notifications actually are in a PWA—because honestly, a lot of people get this wrong. Push notifications in Progressive Web Apps work differently than they do in native mobile apps, but the good news is they can be just as powerful if you set them up properly. Basically, push notifications allow your web app to send messages to users even when they're not actively using your app; pretty neat when you think about it.
The thing is, PWA push notifications rely on three main components working together: the Push API, the Notification API, and a service worker. I know that sounds a bit technical but stick with me—its actually quite straightforward once you see how they all fit together. The Push API handles receiving messages from your server, the Notification API displays those messages to the user, and the service worker acts as the middleman that keeps everything running even when your app isnt open.
Here's what makes PWA notifications different from regular website alerts:
- They work even when the browser is closed—your service worker keeps listening in the background
- They require explicit user permission before they can be sent
- They need a secure connection (HTTPS) to function properly
- They can include actions, images, and other rich content
- Users can manage or revoke permissions at any time through browser settings
Now here's something important to know—browser support for PWA push notifications varies quite a bit. iOS only added support relatively recently and it still has some limitations compared to Android. Chrome and Firefox on desktop have had solid support for years now. This means you need to plan for users who might not be able to receive notifications at all, which is why having a fallback strategy is always a good idea.
The real power of push notifications comes from timing and relevance. Sending too many notifications will get you unsubscribed faster than anything else; trust me on that one. I've seen apps lose half their subscriber base in a week because they went overboard with notifications. The best approach is to only send notifications when they provide genuine value to the user—whether that's a delivery update, a message from another user, or something time-sensitive they actually care about. This strategic approach is crucial for effective user re-engagement.
Setting Up Your Service Worker
Right, so you want to add push notifications to your PWA? Well, the service worker is where it all begins—this is the bit of code that runs in the background, separate from your main web page, and handles all the notification magic. Its basically the engine that powers your entire push notification system. Without it, you're going nowhere fast.
First things first, you need to register your service worker. In your main JavaScript file, you'll add a bit of code that checks if the browser supports service workers (not all of them do, believe it or not) and then registers your service worker file. This usually looks something like: navigator.serviceWorker.register('/sw.js'). That sw.js file is where you'll write all your notification handling code. I always put mine in the root directory to keep things simple—it makes the scope easier to manage, and trust me, scope issues can be a right pain to debug later on.
Inside your service worker file itself, you need to listen for specific events. The main ones for notifications are 'push' (when a notification arrives) and 'notificationclick' (when someone taps on it). You dont need to worry about those just yet, but your service worker needs to be active and listening. When you first register it, the browser will install it, then activate it, and only then will it start intercepting events. This happens automatically but its worth knowing about because sometimes you'll need to force an update if you change your service worker code.
Make sure your service worker file is served over HTTPS—browsers won't register service workers on insecure connections. The only exception is localhost, which is handy for testing but remember to switch to HTTPS before going live.
Understanding Service Worker Scope
The location of your service worker file determines its scope. If you put it in the root directory, it can control your entire site; if its in a subdirectory, it can only control pages within that directory. I've seen developers accidentally limit their service worker scope by putting the file in the wrong folder, which means half their site cant receive notifications. Always check where your service worker lives and what pages it needs to control before you start building out the rest of your notification system.
Requesting User Permission for Notifications
Right, so you've got your service worker registered and ready to go—now comes the bit that honestly makes or breaks most PWAs when it comes to push notifications. You need to ask users for permission. And here's the thing; you can only ask once. Well, technically you can ask again, but if they say no the first time its a nightmare to get them to change their mind later.
I mean, think about how annoying it is when you land on a website and immediately get hit with a permission request before you've even had a chance to see what the site does? Thats exactly what you shouldn't do. The timing of your permission request matters more than you'd think—wait until the user has had a chance to see the value your PWA provides. Maybe they've completed an action, maybe they've been using it for a few minutes. Just don't ask the second they arrive.
The actual code to request permission is pretty straightforward. You'll use the Notification API's requestPermission() method which returns a promise. It looks something like this: Notification.requestPermission().then(function(permission) { ... }). The user gets a browser prompt asking if they want to allow notifications, and they can choose "Allow", "Block", or sometimes "Not Now" depending on the browser. Once they make their choice, you'll get back either "granted", "denied", or "default".
Here's what I always tell clients—make sure you explain why you want to send notifications before you trigger that permission request. Add a nice message or button that says something like "Get notified when your order ships" rather than just randomly asking for permission. Context is everything. Users are much more likely to say yes when they understand whats in it for them, and that leads to better engagement down the line.
Implementing the Push API
Right, so you've got your service worker set up and you've asked users for permission—now comes the fun bit. Actually implementing the Push API. This is where your progressive web app starts feeling less like a website and more like a proper mobile app, and honestly, it's one of my favourite parts of PWA development because this is where things get real.
The Push API lets your service worker listen for push events even when your app isn't open. Pretty cool, right? First thing you need to do is subscribe the user to push notifications. You'll use the PushManager interface for this, which lives inside your service worker registration. When you call the subscribe method, you'll need to pass in your VAPID keys—these are basically like a digital signature that proves the push messages are coming from you and not some random person trying to spam your users.
Getting the Subscription Object
Once you've subscribed the user, you get back a subscription object. This thing is gold—it contains all the info you need to send push messages to that specific user on that specific device. You'll want to send this subscription object to your backend server and store it safely because you're going to need it every time you want to send a push notification. I mean, without it, you've got no way of reaching that user.
The subscription object is unique to each user and device combination, so one person using your PWA on their phone and laptop will generate two separate subscriptions
Here's something that trips people up—the subscription can expire. Users might revoke permissions, clear their browser data, or the browser itself might invalidate old subscriptions. Your code needs to handle these scenarios gracefully; check if a subscription is still valid before trying to use it, and have a way for users to resubscribe if needed.
Creating and Sending Push Messages
Right, so you've got your service worker set up and users have given you permission to send notifications—now comes the interesting bit. Actually sending those push messages. And here's the thing, you cant just fire off notifications from your PWA directly; you need a server to handle this for you. Its a bit annoying at first but it makes sense when you think about it—your users phone needs to receive messages even when your app isnt open.
Your server needs to send a POST request to whats called a push service (like Firebase Cloud Messaging or the browser's own push service). Each user subscription you collected earlier contains an endpoint URL—thats where your server sends the message. You'll also need to include authentication headers using VAPID keys, which basically prove that you're authorised to send notifications to that particular user. Without these keys the push service will reject your request, simple as that.
What Your Push Payload Should Include
When you send a push message from your server it needs to contain the data you want to display. This gets sent as JSON and should include things like:
- Title text for the notification
- Body content (keep it short, people wont read essays)
- Icon URL for branding
- Badge or image if you want to get fancy
- Custom data like links or action buttons
- Tag identifiers to replace old notifications instead of stacking them up
Most developers use libraries like web-push for Node.js or equivalent packages in other languages because handling all the encryption and headers manually is honestly a pain. These libraries do the heavy lifting for you—you just pass in the subscription object, your message payload, and your VAPID keys and they sort out the rest. I mean you could do it manually but why make life harder than it needs to be?
Timing and Message Limits
Be careful with how often you send notifications though. Users will unsubscribe faster than you can say "opt out" if you're bombarding them every five minutes. Think about what actually adds value to their experience, not just what drives engagement metrics on your dashboard. Getting this balance right is essential for maintaining effective retention tactics.
Handling Notifications When Users Click
So you've successfully sent a push notification to your users device—brilliant. But here's the thing, what happens when they actually tap on it? This is where a lot of PWA developers miss a trick really, because the notification click is prime real estate for engagement. You see, when someone clicks your notification they're showing clear intent; they want to know more, and its your job to give them a smooth experience that takes them exactly where they need to go.
Inside your service worker, you'll need to listen for the notificationclick event. This is basically where you define what happens when someone taps your notification—you can open a specific page, focus an existing window, or perform an action without opening anything at all. The most common approach? Opening a URL that's relevant to the notification content. If you sent a notification about a new message, take them straight to that message, not your homepage where they have to hunt for it themselves.
Setting Up Your Click Handler
The code itself isn't too complex but you need to get it right. You'll use event.waitUntil() to keep the service worker alive while your click action completes, and clients.openWindow() to open the desired URL. Here's what you need to consider when building your handler:
- Check if a window with your PWA is already open and focus it instead of opening duplicates
- Store the target URL in your notification data so you know where to send users
- Close the notification once its been handled using event.notification.close()
- Handle errors gracefully in case the window fails to open
Always test your click handlers on both mobile and desktop—the behaviour can differ between platforms and you want to make sure users aren't left hanging when they tap your notification. I've seen cases where notifications worked perfectly in Chrome on desktop but failed miserably on Android because the URL handling was different.
Managing Multiple Windows
One mistake I see constantly is developers not checking for existing windows. If your PWA is already open in another tab, you don't want to open yet another window; instead, focus the existing one and navigate it to the right place. This keeps things tidy and prevents users from ending up with five tabs of your app open at once. Use clients.matchAll() to find existing windows, then either focus one or open a new window if none exist.
Testing Your Push Notifications
Right, so you've built your notification system and now you need to make sure it actually works—this is where most developers skip ahead and live to regret it later. Testing push notifications isn't quite as straightforward as testing other parts of your PWA because you're dealing with service workers, background processes, and external push services. It's a bit mad really how many moving parts are involved.
The first thing I always do is test on my local development environment. You can use tools like Chrome DevTools to simulate push events without actually sending real notifications through a push service. Open DevTools, go to the Application tab, find your service worker, and you'll see a "Push" button—click that and it triggers a push event. Dead simple. This lets you test your notification handling logic before you've even set up a proper backend.
Testing on Real Devices
But here's the thing—desktop testing only gets you so far. You need to test on actual mobile devices because thats where most of your users will be. The notification behaviour differs quite a lot between desktop Chrome, mobile Chrome, iOS Safari, and other browsers. I've seen notifications that looked perfect on desktop but were completely broken on mobile because the payload was formatted wrong or the icons didn't display properly.
What to Check During Testing
Make yourself a proper testing checklist so you don't miss anything important. Here's what I test every single time:
- Does the permission request appear correctly and at the right time?
- Do notifications appear when the app is closed, minimised, and open?
- Are all notification elements (title, body, icon, badge) displaying properly?
- Does clicking the notification open the correct page in your PWA?
- Are action buttons working if you've added them?
- Does the notification sound and vibration work as expected?
- What happens if you send multiple notifications—do they stack or replace each other?
One mistake I see all the time is developers only testing the "happy path" where everything works perfectly. You need to test error scenarios too. What happens if the service worker fails to register? What if the push service is down? What if the users internet connection is spotty? Your app should handle these situations gracefully, not just crash or send broken notifications. Trust me, your users will find every edge case you didn't think to test, so its better to catch them yourself first.
Managing User Preferences and Unsubscribes
Here's something most developers don't think about until its too late—giving users control over their notifications is just as important as sending them in the first place. I've seen perfectly good PWAs lose users because they bombarded people with messages and didn't provide an easy way to stop them. It's a bit mad really, because building an unsubscribe system is actually pretty straightforward.
First up, you need to store user preferences somewhere; this could be in your backend database or even in localStorage if you're keeping things simple. When a user subscribes to your push notifications, save their subscription details along with their preferences—maybe they only want notifications about certain topics, or perhaps they want to pause notifications for a week. The web push API gives you the flexibility to handle all this, you just need to build the interface for it.
Building Your Preference Centre
Create a settings page where users can manage what notifications they receive. Include toggle switches for different notification types and make it dead obvious how to turn everything off completely. When someone wants to unsubscribe, call the unsubscribe() method on their subscription object and remove their details from your database—don't keep sending to endpoints that have unsubscribed because it wastes resources and honestly, its just poor practice.
The fastest way to lose a user's trust is to ignore their notification preferences or make it difficult to unsubscribe from your service worker notifications.
And here's a pro tip from years of dealing with this stuff: always respect the browser's native permission system too. If someone revokes notification permission at the browser level, your service worker won't be able to send anything anyway, but you should still update your records to reflect that change. Check the Notification.permission property periodically so you're not trying to send messages to users who can't receive them anymore—it keeps your engagement metrics accurate and your system running efficiently. This approach is fundamental to successful app marketing strategies.
Adding push notifications to your PWA isn't the easiest thing you'll do this year, but its definitely doable if you follow the steps properly. The main thing is understanding that it's not just about the technical implementation—though that matters a lot—it's about using notifications in a way that actually helps your users rather than annoying them into deleting your app.
I've built dozens of PWAs over the years and I can tell you that the ones that succeed with push notifications are the ones that think carefully about when and why they're sending messages. Sure, you can technically send a notification whenever you want once someone's subscribed, but should you? Probably not. The best approach is to be selective, be useful, and always give people an easy way to customise what they receive.
Here's the thing—PWAs are brilliant because they combine the reach of the web with many of the features people expect from native apps. Push notifications are a huge part of that. They let you re-engage users who might have forgotten about your app, remind them about important updates, or alert them to time-sensitive information. But only if you implement them properly and respect your users boundaries.
Don't rush the implementation just to tick a box. Test thoroughly on different devices and browsers because support can vary; make sure your service worker is registered correctly, double-check that your notifications actually arrive, and verify that clicking them does what users expect. The technical bits we've covered in this guide give you the foundation, but the real skill comes in knowing when to use these tools and when to hold back. Getting that balance right is what separates good PWAs from forgettable ones.
Share this
Subscribe To Our Learning Centre
You May Also Like
These Related Guides

How Do Push Notifications Actually Work In Mobile Apps?

How Many Push Notifications Are Too Many For App Users?
