Push notifications Recommended
Open the exact page the push is about
A tap on a notification opens the page it is about, reuses an open tab when there is one, and marks the item as read.
How to do it
Put a relative path in the payload, such as /orders/1042, never a full outside address. In the service worker's notificationclick handler, focus an open window first and then navigate it, or open a new one. Browsers allow focus only while the click is fresh. Native apps use the same path as a universal link or app link. The page itself checks the session, so a shared phone never shows another account's order.
Example
self.addEventListener('notificationclick', event => {
event.notification.close();
const target = new URL(event.notification.data.path, self.location.origin);
if (target.origin !== self.location.origin) return;
event.waitUntil((async () => {
const [open] = await clients.matchAll({ type: 'window' });
if (!open) return clients.openWindow(target.href);
const focused = await open.focus();
return focused.navigate(target.href);
})());
});
# Server side: only ever put a path from your own router into the payload
from urllib.parse import urlsplit
def push_payload(title: str, path: str, item_id: str) -> dict:
parts = urlsplit(path)
if parts.scheme or parts.netloc or not path.startswith("/"):
raise ValueError("Push links must be relative paths")
return {"title": title, "data": {"path": path, "inbox_item": item_id}}
How to check
A browser test receives a push, clicks it, and lands on /orders/1042 in the open tab. The inbox item for that order is now read.
For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers notifications playbook: https://agentwranglers.se/playbook/notifications/push-notifications/push-deep-links.