better-push
Delivery channels

Test Web Push on devices

Install the PWA and verify web push on real Android and iOS phones.

Web push behaves differently across platforms, and the differences only show up on real hardware. This page covers installing your app as a PWA and verifying push on desktop, Android, and iOS.

Why HTTPS and a real deploy

Service workers and push require a secure context. localhost is exempt, but a phone pointed at your machine's LAN IP is not - so device testing means a public HTTPS URL. Deploy first (the demo uses Railway), then open that URL on the phone.

Desktop (Chrome or Firefox)

  1. Open your HTTPS URL.
  2. Click your register button and accept the permission prompt.
  3. Send a notification from the server and confirm it arrives with the tab in the background or closed (the browser must still be running).

Android (Chrome)

Android Chrome supports push both in a normal tab and as an installed PWA. Test the installed path:

  1. Open the URL in Chrome.
  2. Menu → Add to Home Screen to install.
  3. Open the installed app, log in, and register.
  4. Close the app, send from the server, and the notification appears in the system tray.

iOS and iPadOS 16.4+

iOS supports web push only for web apps added to the Home Screen - not in a regular Safari tab. In a plain tab, window.PushManager is undefined, so better-push's isSupported() correctly returns false there.

Your UI must detect this and guide the user instead of showing a dead button:

const isIos = /iphone|ipad|ipod/i.test(navigator.userAgent);
const standalone =
  window.matchMedia("(display-mode: standalone)").matches ||
  (navigator as unknown as { standalone?: boolean }).standalone === true;

const iosNeedsInstall = isIos && !standalone;

When iosNeedsInstall is true, show "Share → Add to Home Screen, then open the installed app" instead of the register button.

The flow:

  1. Open the URL in Safari - verify the install instructions appear (not a broken button).
  2. Share → Add to Home Screen.
  3. Open the installed app, tap register (the permission prompt appears on the tap), and allow.
  4. Close the app, send from the server, and the notification appears on the lock screen.

The user-gesture rule

Both platforms require the permission prompt to follow a user gesture. Never prompt automatically on load - always trigger register() from a button tap. better-push's React hook never prompts on its own for exactly this reason.

PWA requirements checklist

To be installable, your app needs:

  • A web app manifest with name, short_name, start_url, display: "standalone", theme_color, background_color, and 192×192 and 512×512 icons (include one maskable variant).
  • iOS metadata: an apple-touch-icon (180×180) and appleWebApp settings.

The demo app under apps/demos/next implements all of this and is the reference.

On this page