<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/medium-luxb9umgz" -->

---
title: Medium | daily.dev
description: A field-notes style guide covers implementing Web Push notifications in a Next.js App Router project, detailing the three required pieces (service worker at...
canonical: https://daily.dev/posts/medium-luxb9umgz
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Medium | daily.dev
og:description: A field-notes style guide covers implementing Web Push notifications in a Next.js App Router project, detailing the three required pieces (service worker at...
og:url: https://daily.dev/posts/medium-luxb9umgz
og:image: https://api.daily.dev/og/posts/lUxb9UMgZ.png
og:image:alt: Medium
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Medium

**[Medium](https://daily.dev/sources/medium_js)** · 10 min read · 0 upvotes · 0 comments

## Summary

A field-notes style guide covers implementing Web Push notifications in a Next.js App Router project, detailing the three required pieces (service worker at the origin root, VAPID key pair, Node.js-runtime route handler) and the extra iOS Safari requirement of installing the site to the Home Screen. It explains service worker scope rules, sending pushes with the web-push package via Promise.allSettled, handling 404/410 dead subscriptions, iOS Safari's Push API limitations since 16.4, Safari 18.4's Declarative Web Push addition, and common production pitfalls like stale service workers, permission UX mistakes, fan-out performance, and HTTPS requirements. It also compares Web Push against Server-Sent Events and WebSockets and includes an FAQ on Firebase Cloud Messaging, silent pushes, and testing.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://medium.com/@ahmed.bis.iti/web-push-in-the-next-js-6ba21a6c0f95>

## Questions this post answers

### Why does my Web Push permission prompt do nothing on iOS Safari?

iOS Safari only exposes the Push API to sites installed on the Home Screen; in a normal Safari tab, window.PushManager is undefined and no prompt or error appears. Web Push landed in iOS 16.4 in March 2023 with this constraint. The fix is to detect standalone mode with a display-mode media query and show install instructions instead of a broken button when the user is in a regular tab.

_Track platform quirks like this one on daily.dev before they cost you a week of debugging._

### How should I handle a Web Push subscription that returns a 404 or 410 error?

Delete the subscription immediately, since a 404 or 410 status from the push service means the endpoint will never be valid again. Subscriptions die silently when users clear site data, reinstall a browser, or revoke permission, so pruning on these status codes during Promise.allSettled batch sends is the main recovery mechanism, since browser-fired pushsubscriptionchange events are unreliable outside Chrome.

_Developers building reliable notification systems compare error-handling patterns like this on daily.dev._

### What is Declarative Web Push in Safari 18.4 and how does it differ from the classic Web Push flow?

Declarative Web Push, added in Safari 18.4 in March 2025, lets the server send a JSON payload with a web_push key and a notification object, and the browser renders the notification without invoking the service worker's push handler at all. It improves reliability on Apple platforms but is additive, meaning the classic service worker path is still needed for Chrome and Firefox.

_Keep up with browser-specific push API changes like this via daily.dev when planning cross-browser support._

## Similar posts on daily.dev

- [Sending Notifications](https://daily.dev/posts/sending-notifications-rn6o9kw1e) · Larablog · 1 upvotes · 0 comments
- [Deep Linking and Navigation from Notifications](https://daily.dev/posts/deep-linking-and-navigation-from-notifications-zyqz11wln) · Medium · 0 upvotes · 0 comments
- [Live Activities with Expo, End to End: Client and Backend — Expo blog](https://daily.dev/posts/live-activities-with-expo-end-to-end-client-and-backend-expo-blog-jwfjdu3w2) · Expo Blog · 0 upvotes · 0 comments
- [Build a Next.js 16 PWA with true offline support](https://daily.dev/posts/build-a-next-js-16-pwa-with-true-offline-support-iyrolodea) · LogRocket · 5 upvotes · 0 comments

---

Tags: [#nextjs](https://daily.dev/tags/nextjs)

[View this post on daily.dev](https://daily.dev/posts/medium-luxb9umgz)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Medium","url":"https://daily.dev/posts/medium-luxb9umgz","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/medium-luxb9umgz"},"datePublished":"2026-08-20T07:42:31.730Z","dateModified":"2026-08-20T07:55:32.782Z","description":"A field-notes style guide covers implementing Web Push notifications in a Next.js App Router project, detailing the three required pieces (service worker at...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/d6ab0a9a223ee01bc82d647f54feb2d2?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/d6ab0a9a223ee01bc82d647f54feb2d2?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Medium","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Medium","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/medium","url":"https://daily.dev/sources/medium_js"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/medium-luxb9umgz","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"nextjs","timeRequired":"PT10M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Medium","item":"https://daily.dev/sources/medium_js"},{"@type":"ListItem","position":3,"name":"Medium"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/medium-luxb9umgz#faq","mainEntity":[{"@type":"Question","name":"Why does my Web Push permission prompt do nothing on iOS Safari?","acceptedAnswer":{"@type":"Answer","text":"iOS Safari only exposes the Push API to sites installed on the Home Screen; in a normal Safari tab, window.PushManager is undefined and no prompt or error appears. Web Push landed in iOS 16.4 in March 2023 with this constraint. The fix is to detect standalone mode with a display-mode media query and show install instructions instead of a broken button when the user is in a regular tab. Track platform quirks like this one on daily.dev before they cost you a week of debugging."}},{"@type":"Question","name":"How should I handle a Web Push subscription that returns a 404 or 410 error?","acceptedAnswer":{"@type":"Answer","text":"Delete the subscription immediately, since a 404 or 410 status from the push service means the endpoint will never be valid again. Subscriptions die silently when users clear site data, reinstall a browser, or revoke permission, so pruning on these status codes during Promise.allSettled batch sends is the main recovery mechanism, since browser-fired pushsubscriptionchange events are unreliable outside Chrome. Developers building reliable notification systems compare error-handling patterns like this on daily.dev."}},{"@type":"Question","name":"What is Declarative Web Push in Safari 18.4 and how does it differ from the classic Web Push flow?","acceptedAnswer":{"@type":"Answer","text":"Declarative Web Push, added in Safari 18.4 in March 2025, lets the server send a JSON payload with a web_push key and a notification object, and the browser renders the notification without invoking the service worker's push handler at all. It improves reliability on Apple platforms but is additive, meaning the classic service worker path is still needed for Chrome and Firefox. Keep up with browser-specific push API changes like this via daily.dev when planning cross-browser support."}}]}
```

