Jump Ahead
PWA Push Notifications: Do They Actually Work in 2026?
Nobody seemed to know. So I shipped a PWA and found out.
Who This Is For
- You have basic knowledge of web development.
- You're building something mobile-first.
- You need push notifications to work on every device.
- You’re building a product that basically needs to feel like a native app on both iOS and Android
- And for some reason (timeline, cost, App Store politics), shipping a native mobile app isn't an option.
Not-Scary Terms (I Swear)
Getting push notifications to work on the web involves a few pieces. Some built into the browser, some you build yourself.
Skip if you know these already.
- PWA (Progressive Web App): A website that can be "installed" on your phone's home screen and behave like a native app (full-screen, no browser bar, works offline). It's still a web app under the hood.
- Service Worker: A small script that runs in the background, separate from your web page. It's what makes offline mode and push notifications possible. On both Android and iOS, the browser requires a service worker to be registered before it will show any notifications.
- Notification API: A feature that comes built into every modern web browser (like how browsers can already access your camera or location). It's what triggers that "Allow / Block" popup when a website wants to send you notifications. You don't install it. It's there to use. EXCEPT on iOS mobile browsers, where it only shows up under specific conditions (more on that below).
- Standalone Mode: When a PWA is opened from a home screen icon instead of a browser tab. It looks and feels like a native app. On iOS, this is the only context where the Notification API is available.
The Question
To be clear, this demo does NOT test whether push notifications deliver reliably on PWAs.
The question is this:
Can you build a PWA that ask users for notification permission on every major platform in 2026? In other words, can you get a web app to show the "Allow Notifications" prompt in the first place, no matter what device or browser combo?
Short answer: yes.
Longer answer: yes, but if you care about iPhone users, there's a hoop to jump through first.
Why I built this
I hit up Reddit, Google, AI.
Every answer was either outdated, hedged, or lacking proof.
None of them gave me the confidence to commit to my (favorite) assumption that ItJustWorks™️ before moving forward. I needed that confidence, though. Fast. So here it is.
Wait, Don't Web Notifications Just Work?
If you've gotten a notification from your browser on your computer, you might be wondering what the problem is. Fair question.
- Desktop browsers have supported the notification permission prompt for years. No service worker needed. Desktop native apps (using Electron, Tauri) have full OS-level access. So yes, desktop notifications = a solved problem.
- Android mobile browsers are also mostly fine. You need a service worker for notifications themselves to display, , but calling
Notification.requestPermission()displays the permission prompt as expected. - iOS mobile browsers are the problem, and if you're targeting US users, that's more than half your mobile traffic.
The Approach
Like most AI-assisted projects, thinking about what I wanted took the longest: about 15–30 minutes going back and forth with Gemini and ChatGPT to craft a prompt for v0. This is the TLDR of that effort:
Build a Next.js web app that can be installed as a PWA that tests the notification permission flow on iOS and Android, with platform detection, home screen app vs. in-browser detection, no backend, and a debug panel that shows me exactly which gates are passing or failing on a real device.
I fed a prompt like this to v0, and it generated the working demo app in a minute or two. I clicked a button to deploy to Vercel.
What It Takes
These are the 5 gates that must all pass before a PWA can show the "Allow Notifications" prompt:
- HTTPS: The browser won't even expose the Notification API without a secure connection.
- Web App Manifest with
display: standalone: This is what tells the phone "I'm an app, not just a website." Without it, iOS won't enter PWA mode from the home screen. - A registered Service Worker: The background script. On both Android and iOS, the browser requires one before it will show any notifications, even if it does literally nothing.
- A user gesture: You can't fire the permission prompt on page load. It has to come from a deliberate action, like tapping an "Allow Notifications" button.
- Standalone mode (iOS only): This is the big one. On iPhone, none of the above matters if the user is still in a browser tab. The Notification API only exists after they Add to Home Screen and open the app from the icon.
Miss any one of these and the prompt silently won't fire. That's what the debug panel is for — it shows you which gates are green and which aren't.
Observations
There are two paths through the enable permissions flow, and your platform determines which one you get.
- Android / Desktop: The Notification API is available right away. User clicks "Allow Notifications," the browser shows the native permission prompt, done. If they grant it, a test notification fires through the service worker. Cue confetti.


- iOS (any browser): The Notification API doesn't exist in a mobile browser tab. It only appears when the app is running in standalone mode. If your code calls
Notification.requestPermission()from a browser tab, it silently fails, throws, or returns undefined. No error message. It just doesn't work.. And the user is left staring like “…hello?”- Once you launch the app from the installed home screen icon, the
NotificationAPI returns and the flow works exactly like it did in the Desktop browser. This entire iOS browser detection flow is four lines:if (deviceInfo.isIOS && !deviceInfo.isStandalone) { setShowIOSOverlay(true); return;}
- Once you launch the app from the installed home screen icon, the
Different States
This is what it looks like on Chrome or Safari on an iPhone (Notice that the app detects Notification and Permission are unsupported, that the platform is iOS, and the user is not visiting the web app in standalone mode):

This is what it looks like before launch in standalone mode.

This is what you see when you click “Allow Notifications” in a browser on iOS. Instead of calling an API that doesn’t exist, it shows you a ✨user friendly✨ modal walking you through the install flow: Share → tap "Add to Home Screen" → open from the Home Screen icon:

This is what it looks like when you click “Allow Notifications” in standalone mode:
Some Gotchas
- Service workers and Next.js don't mix cleanly. The usual approach is putting
sw.jsin the/publicdirectory, but Next.js serves static files with aggressive caching headers and won't let you setService-Worker-Allowed.- The fix: serve the service worker via a Route Handler at
/app/sw.js/route.ts. The URL is still/sw.jsfrom the browser's perspective, but you get full control over headers.
- The fix: serve the service worker via a Route Handler at
- The debug panel isn't decoration. It shows protocol (must be HTTPS), service worker registration status, standalone mode, and Notification API availability — all color-coded. Every one of those is a gate that must pass before
requestPermission()will work. On a physical device, this is the fastest way to figure out why notifications aren't prompting. - iPads lie about what they are. iPadOS 13+ reports itself as
"MacIntel"with a desktop user-agent string. Without checkingnavigator.maxTouchPoints > 1, iPads get classified as desktop and try to call an API that doesn't exist in iOS.
Try It Yourself
Visit the demo on your phone, your desktop, or both.
Watch the debug values change as you move between a regular browser tab and an installed home screen app: v0-notification-permission-pwa.vercel.app
If something doesn't work on your device or browser, open an issue on the GitHub repo. I'll respond.