Page updated Feb 28, 2024

Service Worker

AWS Amplify ServiceWorker class enables registering a service worker in the browser and communicating with it via postMessage events, so that you can create rich offline experiences with Push APIs and analytics.

After registering the service worker, the ServiceWorker module will listen and attempt to dispatch messages on state changes, and it will record analytics events based on the service worker's lifecycle.

postMessage events are currently not supported in all browsers. For details and to learn more about Service Worker API, please visit here.

Installation

Import ServiceWorker and instantiate a new instance (you can have multiple workers on different scopes):

1import { ServiceWorker } from 'aws-amplify/utils';
2const serviceWorker = new ServiceWorker();

Working with the API

register()

You can register a service worker for the browser with register method.

First, you need to create a service worker script service-worker.js. Your service worker script includes cache settings for offline access and event handlers for related lifecycle events. Click to see a sample service worker script for your app.

Make sure that worker script is included with your build and provide a script path relative to the source directory when registering:

1// Register the service worker with `service-worker.js` with service worker scope `/`.
2registeredServiceWorker = await serviceWorker.register('/service-worker.js', '/');

This method will enable web push notifications for your app. If your app is not previously subscribed to the push service to receive notifications, a new subscription will be created with the provided public key.

1serviceWorker.enablePush('BLx__NGvdasMNkjd6VYPdzQJVBkb2qafh')

You need a web push service provider to generate the public key, and sending the actual push notifications. To test push messages with a non-production environment, you can follow this tutorial.

Handling a Push Notification

To handle incoming push notifications in your service worker, your script should register an event handler for push event.

In your service-worker.js file, add following event listener:

1/**
2 * Listen for incoming Push events
3 */
4
5addEventListener('push', (event) => {
6 var data = {};
7 console.log('[Service Worker] Push Received.');
8 console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);
9
10 if (!(self.Notification && self.Notification.permission === 'granted'))
11 return;
12
13 if (event.data)
14 data = event.data.json();
15
16 // Customize the UI for the message box
17 var title = data.title || "Web Push Notification";
18 var message = data.message || "New Push Notification Received";
19 var icon = "images/notification-icon.png";
20 var badge = 'images/notification-badge.png';
21 var options = {
22 body: message,
23 icon: icon,
24 badge: badge
25 };
26
27 event.waitUntil(self.registration.showNotification(title,options));
28
29});

For more information about Notifications API, please visit here.

send()

send method sends a message to your service worker, from your web app. Remember that your app's code and service worker script work in different contexts, and the communication between the two is possible with send() method.

This is useful when you want to control your service worker logic from your app, such as cleaning the service worker cache:

1registeredServiceWorker.send({
2 'message': 'CleanAllCache'
3 });

For more information about Message API, please visit here.

Receiving Messages

To receive the messages in your service worker, you need to add an event handler for message event.

In your service-worker.js file, add the following event listener:

1/**
2 * The message will receive messages sent from the application.
3 * This can be useful for updating a service worker or messaging
4 * other clients (browser restrictions currently exist)
5 * https://developer.mozilla.org/en-US/docs/Web/API/Client/postMessage
6 */
7 addEventListener('message', (event) => {
8 console.log('[Service Worker] Message Event: ', event.data)
9 })

Monitoring Lifecycle Events

If you enable AWS Amplify Analytics category, ServiceWorker module automatically tracks service worker state changes and message events.

You can see those analytics events are related metrics in Amazon Pinpoint console.

API Reference

For the complete API documentation for ServiceWorker module, visit our API Reference

Example Service Worker

1var appCacheFiles = [
2 '/',
3 '/index.html'
4],
5// The name of the Cache Storage
6appCache = 'aws-amplify-v1';
7
8/**
9 * The install event is fired when the service worker
10 * is installed.
11 * https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
12 */
13addEventListener('install', (event) => {
14 console.log('[Service Worker] Install Event', event)
15 event.waitUntil(
16 caches.open(appCache).then(function(cache) {
17 return cache.addAll(appCacheFiles);
18 })
19 );
20})
21
22/**
23 * The activate vent is fired when the service worker is activated
24 * and added to the home screen.
25 * https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
26 */
27addEventListener('activate', (event) => {
28 console.log('[Service Worker] Activate Event ', event)
29})
30
31/**
32 * The fetch event is fired for every network request. It is also dependent
33 * on the scope of which your service worker was registered.
34 * https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
35 */
36addEventListener('fetch', function(event) {
37 //return fetch(event.request);
38 console.log('[Service Worker] Fetch: ', event);
39 let url = new URL(event.request.url);
40 //url.pathname
41 event.respondWith(
42 caches.match(event.request).then(function(resp) {
43 return resp || fetch(event.request).then(function(response) {
44 return caches.open(appCache).then(function(cache) {
45 if (event.request.method === 'GET') {
46 cache.put(event.request, response.clone());
47 }
48 return response;
49 });
50 });
51 })
52 );
53});
54/**
55 * The message will receive messages sent from the application.
56 * This can be useful for updating a service worker or messaging
57 * other clients (browser restrictions currently exist)
58 * https://developer.mozilla.org/en-US/docs/Web/API/Client/postMessage
59 */
60addEventListener('message', (event) => {
61 console.log('[Service Worker] Message Event: ', event.data)
62})
63
64/**
65 * Listen for incoming Push events
66 */
67addEventListener('push', (event) => {
68 console.log('[Service Worker] Push Received.');
69 console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);
70
71 if (!(self.Notification && self.Notification.permission === 'granted'))
72 return;
73
74 var data = {};
75 if (event.data)
76 data = event.data.json();
77
78 var title = data.title || "Web Push Notification";
79 var message = data.message || "New Push Notification Received";
80 var icon = "images/notification-icon.png";
81 var badge = 'images/notification-badge.png';
82 var options = {
83 body: message,
84 icon: icon,
85 badge: badge
86 };
87 event.waitUntil(self.registration.showNotification(title,options));
88});
89
90/**
91 * Handle a notification click
92 */
93addEventListener('notificationclick', (event) => {
94 console.log('[Service Worker] Notification click: ', event);
95 event.notification.close();
96 event.waitUntil(
97 clients.openWindow('https://aws-amplify.github.io/amplify-js')
98 );
99});