Why push notifications matter
Push notifications let web apps surface small, timely pieces of information: a breaking update, a deadline, or an action the user needs to take. The visual presentation differs by platform, but the underlying mechanism is consistent.
Traditional web communication is request-driven: the browser asks the server for data. Web push inverts that model. Your server can send a message when it makes sense for your app, and a push service delivers it to a unique URL assigned to each subscribed service worker. Delivering a message to that URL fires an event on the service worker, which can then display a notification.
Used well, notifications pull users back to an app with fresh, relevant information rather than relying on them to remember to return.
Creating notifications with the Notifications API
To create a notification, instantiate a Notification object with a title string and an options object:
let title = 'Hi!';
let options = {
body: 'Very Important Message',
/* other options can go here */
};
let notification = new Notification(title, options);
The title renders in bold while the notification is active; the body option carries supporting text.
Displaying a notification requires explicit user permission:
Notification.requestPermission();
The push delivery pipeline
Real push power comes from combining service workers with push technology. Service workers run in the background and can render notifications even when your app is not on screen. Push technology lets the server initiate that process at the right moment.
A typical flow works like this: the client registers a service worker and subscribes to push. The server sends a message to the endpoint returned by that subscription. The example implementation below uses vanilla JavaScript on the client and service worker, an express server on Node.js, and the web-push npm package to send messages. The client communicates with the server by posting to a URL it exposes.
Step one: register and subscribe
- The client registers a service worker using
ServiceWorkerContainer.register(). The service worker stays alive in the background after registration:navigator.serviceWorker.register('sw.js'); - The client asks the user for notification permission:
Notification.requestPermission(); - The service worker calls
PushManager.subscribe(), supplying the app's API key as an identifier. The push service—Firebase Cloud Messaging, for example—responds by creating a unique URL for that service worker, called the subscription endpoint:navigator.serviceWorker.register('sw.js').then(sw => { sw.pushManager.subscribe({ /* API key */ }); }); - The client sends the subscription endpoint to the app server, which stores it:
navigator.serviceWorker.register('sw.js').then(sw => { sw.pushManager.subscribe({ /* API key */ }).then(subscription => { sendToServer(subscription, '/new-subscription', 'POST'); }); });app.post('/new-subscription', (request, response) => { // extract subscription from request // send 'OK' response });
Step two: send and display
- The server sends a notification to the stored subscription endpoint:
const webpush = require('web-push'); let options = { /* config info for cloud messaging and API key */ }; let subscription = { /* subscription created in Part 1*/ }; let payload = { /* notification */ }; webpush.sendNotification(subscription, payload, options); - The push service routes the message to the endpoint, firing a
pushevent targeted at the service worker. The service worker handles the event and shows the user a notification:self.addEventListener('push', (event) => { let title = { /* get notification title from event data */ } let options = { /* get notification options from event data */ } showNotification(title, options); }) - The user clicks or acts on the notification, bringing the web app to the foreground if it was not already active.
Where to go from here
The fastest way to build familiarity is to walk through an implementation end to end. Codelab tutorials are available that cover each step: registering a service worker, requesting permission, subscribing to a push service, sending a message from the server, and handling the push event to display a notification.



