Frontend Development 16 min read

How to Implement Offline Web Push Notifications in Chrome with Service Workers

This article examines how to implement offline Web Push notifications in Chrome using Service Workers, covering background, technical concepts such as BrowserId and the Notifications API, step-by-step code for permission handling, key generation, BrowserId retrieval, and server‑side message delivery.

Trip Tech Team
Trip Tech Team
Trip Tech Team
How to Implement Offline Web Push Notifications in Chrome with Service Workers

1. Research Background

With the continuous development of Internet technology, more enterprises prefer to use Internet solutions such as mobile apps and Web sites to host parts of their business. User reachability is a key metric. In mobile apps, push notifications address this; on Web sites, solutions like SMS, in‑site messages, and pop‑ups have drawbacks such as cost, requiring the user to be online, or degrading user experience. Compared with app push, low‑cost, offline‑capable Web push solutions are scarce. This article explores an offline Web Push solution for Chrome browsers.

2. Related Theory and Technical Overview

The proposed offline Web Push solution assumes the user is not currently visiting the enterprise Web site. By registering a Service Worker and obtaining a BrowserId, the server can send the BrowserId and message to Google FCM, which delivers the message to the browser. The Service Worker then uses the Notifications API to display the message.

2.1 Web Push Technical Overview

The solution consists of two parts: BrowserId collection and message push. When a user visits the site, the site requests push permission, obtains a BrowserId via the Service Worker, and stores it in a database. Later, the site sends the message and BrowserId to Google FCM, which forwards the message to the browser, where the Service Worker displays it.

2.2 Service Worker

Service Workers run in a background thread, are event‑driven, and can intercept network requests, providing offline caching and push handling capabilities. Their independent thread and event‑driven nature allow them to stay active when the user is not on the site and respond to FCM push events.

2.3 BrowserId

When a page requests a BrowserId, the Service Worker returns three fields—auth, p256dh, and endpoint—that together identify a browser. These fields are used by FCM to target the correct client.

2.4 Notifications Interface

The browser Notifications interface lets web pages display system notifications outside the page viewport. Developers must obtain user permission and can configure title, body, icon, and other parameters via the Notification object.

3. Offline Push Solution Based on Web Push

The implementation is divided into BrowserId collection and message push, as illustrated in the flow diagrams.

3.1 Get Permission

When a user visits the site, the page calls Notification.requestPermission() , which returns a Promise resolving to granted , denied , or default .

<code>const getPermission = () => {
  return Notification.requestPermission().then(permission => {
    return permission;
  });
};</code>

3.2 Generate VAPID Keys and Get BrowserId

First generate a public/private VAPID key pair using the web-push library. The keys are generated once and reused.

<code>const webPush = require('web-push');
const generateKeys = () => {
  const { publicKey, privateKey } = webPush.generateVAPIDKeys();
  return { publicKey, privateKey };
};</code>

Then obtain the BrowserId via the registered Service Worker.

<code>const getBrowserId = (publicKey, scope) => {
  return navigator.serviceWorker
    .register('/webpush/sw.js', { scope })
    .then(reg => {
      return reg.update().then(swInstance => {
        return swInstance.pushManager.getSubscription().then(subscription => {
          if (subscription) {
            return subscription;
          }
          return swInstance.pushManager.subscribe({
            userVisibleOnly: true,
            applicationServerKey: publicKey,
          });
        });
      });
    })
    .then(subscription => {
      return subscription;
    });
};</code>

3.3 Message Push

After collecting BrowserIds, the server sends a push message to FCM using the web-push library.

<code>const webPush = require('web-push');

async sendPush() {
    const { subscription } = this.ctx.request.body || {};
    const payload = {
      title: 'Message From TRIP',
      body: 'Test Message',
      icon: 'https://dimg04.c-ctrip.com/images/a107170000012i7sb4D1E.png',
      requireInteraction: true,
      data: {
        link: 'https://hk.trip.com',
      },
    };
    const options = {
      TTL: 0,
      vapidDetails: {
        publicKey: PUBLICKEY,
        privateKey: PRIVATEKEY,
      },
      contentEncoding: 'aesgcm',
    };

    await webPush.sendNotification(subscription, JSON.stringify(payload), options)
      .then(() => {
        console.log('Send Notification Successfully.');
        this.ctx.status = 201;
      })
      .catch(error => {
        console.log('[Webpush Error Info]: ', error);
        this.ctx.status = 500;
      });
}</code>

The Service Worker listens for the push event and displays the notification.

<code>self.addEventListener('push', function(event) {
  const payload = event.data.json();
  event.waitUntil(
    getPayload(payload)
      .then(payload => {
        self.registration.showNotification(payload.title, {
          ...payload,
        });
      })
  );
});</code>

4. Conclusion

Web Push support is still experimental and varies across browsers. The presented solution is feasible, but if users deny permission, re‑enabling it requires navigating deep privacy settings, which may affect business design.

Frontend DevelopmentChromeNotificationsservice-workerweb pushBrowserId
Trip Tech Team
Written by

Trip Tech Team

Trip.com technology team, focused on internationalization and localization solutions.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.