Vue service worker for WebPush Notifications
Building a Vue PWA with Web Push Notifications enabled
Web Push Notifications & Service Workers
Web Push Notifications
Web Push Notifications are one of the most important feature for a PWA in order to be compared with native apps. User will get notification even if your app is not opened in the browser. If you want to learn more about them or you don’t know much about the Web Push Notifications you can find more info here
Service Workers
In order to work, Web Push Notifications need a service worker, basically a javascript process that runs indipendently from your app. To learn more about service workers I suggest you to read the documentation in order to understand better what I will present below. More info and some good example here
PWA Service Worker in Vue
Default service workers
Using Vue CLI with the PWA template you will get a service worker automatically created, registered and working (production env). The standard service worker is created by the build process by registerServiceWorker.js :
/* eslint-disable no-console */
import { register } from 'register-service-worker'
if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
ready () {
console.log(
'App is being served from cache by a service worker.\n' +
'For more details, visit https://goo.gl/AFskqB'
)
},
registered () {
console.log('Service worker has been registered.')
},
cached () {
console.log('Content has been cached for offline use.')
},
updatefound () {
console.log('New content is downloading.')
},
updated () {
console.log('New content is available; please refresh.')
},
offline () {
console.log('No internet connection found. App is running in offline mode.')
},
error (error) {
console.error('Error during service worker registration:', error)
}
})
}
src/registerServiceWorker.js
The result after the build will be service-worker.js
in the root of the dist folder
/**
* Welcome to your Workbox-powered service worker!
*
* You'll need to register this file in your web app and you should
* disable HTTP caching for this file too.
* See https://goo.gl/nhQhGp
*
* The rest of the code is auto-generated. Please don't update this file
* directly; instead, make changes to your Workbox build configuration
* and re-run your build process.
* See https://goo.gl/2aRDsh
*/
importScripts("https://storage.googleapis.com/workbox-cdn/releases/3.6.3/workbox-sw.js");
importScripts(
"precache-manifest.c9d50e7b61e4d64b7ee75abc3a4955c0.js"
);
workbox.core.setCacheNameDetails({prefix: "myappname"});
/**
* The workboxSW.precacheAndRoute() method efficiently caches and responds to
* requests for URLs in the manifest.
* See https://goo.gl/S9QRab
*/
self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.suppressWarnings();
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
The auto-generated service worker is a standard template built loading a Workbox CDN and it’s a basic caching system of the js files.
So what about I want setup my service worker to enable WebPush notifications?
The only way to get them working is to create a custom service worker.
Custom service worker
The best solution to me in order to create a custom service worker that works with the Web Push Notifications was to change the auto-generated service worker.
How to do that? The process is quite simple:
- change or create a
vue.config.js
in the root of your app (not the src folder) adding the following
module.exports = {
pwa: {
workboxPluginMode: "InjectManifest",
workboxOptions: {
swSrc: "src/service-worker.js",
}
}
}
vue.config.js
This tell to the Vue build process to inject the service worker source from src/service-worker.js
that you have to create.
- create an empty js file
src/service-worker.js
and add
self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.suppressWarnings();
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
//Web Push Notifications//
let click_open_url
self.addEventListener('push', function(event) {
let push_message = event.data.json()
// push notification can send event.data.json() as well
click_open_url = push_message.notification.data.url
const options = {
body: push_message.notification.body,
icon: push_message.notification.icon,
image: push_message.notification.image,
tag: 'alert'
};
event.waitUntil(self.registration.showNotification(push_message.notification.title, options));
});
self.addEventListener('notificationclick', function(event) {
const clickedNotification = event.notification;
clickedNotification.close();
if ( click_open_url ){
const promiseChain = clients.openWindow(click_open_url);
event.waitUntil(promiseChain);
}
});
Basically we keep the standard auto-generated service-worker adding our push notification event listener. In this way you enable your PWA to get Web Push Notifications.
How to test it? In order to test you need to build your app, and a Web Push Notifications service (Firebase, Google Cloud Messaging, ecc.) or you can create your own.
Important: push notifications need subscription by the user.
Create a VAPID Web Push Notification Service
Click here to learn how to create a VAPID Web Push Notification service
See you soon!