Web push notifications from PHP, without a service in between

Web push has a reputation for complexity that it does not deserve. There is no third-party service to sign up for, and no proprietary protocol.

What a subscription is

  • An endpoint: a URL at the browser vendor’s push service.
  • A public key and an authentication secret, generated by the browser.

Your server encrypts the payload with those, and POSTs it to the endpoint. The push service relays it without ever seeing the content. That is the part people miss: the vendor cannot read your notifications, the encryption is end to end between your server and the browser.

VAPID

You identify yourself to the push service with a signed JWT, which is what VAPID is. One key pair for your whole application, and a contact address so the vendor can reach you if something goes wrong. Nothing to register.

Clean up your subscriptions

Subscriptions expire. A user clears their data, uninstalls, or revokes permission, and your endpoint starts returning 404 or 410. Those two codes mean « delete this subscription », not « retry later ».

A push table nobody prunes grows forever and slows every send, because you keep paying for requests that can never succeed.

The service worker side

The worker listens for push and calls showNotification. Keep that handler trivial and synchronous in spirit: a worker that awaits a slow fetch before showing anything gets killed, and the notification never appears.

That failure is platform-specific and quiet. pwa-bundle 1.5.8 fixed a case where a push event was silently dropped on Android Chrome, which is exactly the kind of bug you cannot reproduce on your desktop.

web-push handles the encryption and the VAPID signing, with a Symfony bundle.