How to build PWA w/ Vue CLI 3

PR — Hiring Designer Co-founder

I’m developing Real-time Handwriting Collaboration Tool in time for the iPad OS release this fall.

Please check out these posts if you’re interested in this product & career!

What’s PWA?

There’re the following functions about PWA (Progressive Web App).

  • Service Workers
  • Add to Home Screen
  • Push Notifications

By using PWA, you can provide UX that is similar to Native Application to users even through you develop it as Web Application.

I’m going to try these functions with Vue.js.

PWA w/ Vue CLI 3

Demo

https://vue-pwa-tutorial.firebaseapp.com

Source Code

vue-pwa-tutorial

Tutorial

  1. Install Vue CLI 3

Ref. Installation | Vue CLI 3

$ npm install -g @vue/cli
  1. Create a new project
$ vue create vue-pwa-tutorial
  1. Select manually
Vue CLI v3.3.0
? Please pick a preset: 
  default (babel, eslint) 
❯ Manually select features
  1. Select PWA

Typescript, Router, Vuex as you like.

Vue CLI v3.3.0
? Please pick a preset: Manually select features
? Check the features needed for your project: 
❯◉ Babel
 ◉ TypeScript
 ◉ Progressive Web App (PWA) Support
 ◉ Router
 ◉ Vuex
 ◯ CSS Pre-processors
 ◉ Linter / Formatter
 ◯ Unit Testing
 ◯ E2E Testing
  1. After that appropriately
Vue CLI v3.3.0
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, TS, PWA, Router, Vuex, Linter
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript for auto-detected polyfills? Yes
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a linter / formatter config: TSLint
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? Yes
? Save preset as:
  1. Initialize
Vue CLI v3.3.0
✨  Creating project in /Users/zyyx-kubo/WVVUProjects/chatty/vue-pwa-tutorial.
🗃  Initializing git repository...
⚙  Installing CLI plugins. This might take a while...
  1. Run web server
$ cd vue-pwa-tutorial/
$ npm run serve
  1. Access to localhost


PWA — Service Workers

If you start with npm run serve , Service Workers will not work as follows.

To check the behavior Service Workers you need to build with npm run build .
If you publish the ./dist directory using Web Server for Chrome, you can check that Service Workers is working as follows. (Usually start with npm run servewhen you don’t use Service Workers)

$ npm run build
 DONE  Build complete. The dist directory is ready to be deployed.

Static contents(*.html, *.css, *.js, *.txt) are cached.

Checked Developer Tool > Application > Service Workers > Update on reload, and Cache is cleared every time on browser reload. Otherwise delete the target file from Cache Storage.

PWA — Add to Home Screen

Web App Manifest

In order to display the “Add to Home Screen” dialog, JSON formatted Web App Manifest file is required.

If you selected PWA with Vue CLI, it will be create by default, so use that as it is.

./public/manifest.json
{
  "name": "vue-pwa-tutorial",
  "short_name": "vue-pwa-tutorial",
  "icons": [
    {
      "src": "./img/icons/android-chrome-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "./img/icons/android-chrome-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "start_url": "./index.html",
  "display": "standalone",
  "background_color": "#000000",
  "theme_color": "#4DBA87"
}

Local Environment

Deploy to the server because you can’t check it by mobile phone.

Build Demonstration Environment by Firebase Hosting

As a reason to use Firebase, I will try Push Notifications next time. so it’s a foundation for that.

Ref. Deployment Firebase | Vue CLI 3

  1. Create a new project on Firebase

At first sign in to Firebase console with Google account, and create a new project.

  1. Deploy

Installing Firebase CLI because deployment runs with command line.

$ npm install -g firebase-tools
$ firebase login

Initialization by project root.

$ firebase init hosting

? Select a default Firebase project for this directory: (Use arrow keys)
  [don't setup a default project] 
❯ vue-pwa-tutorial (vue-pwa-tutorial) 
  [create a new project] 

? What do you want to use as your public directory? (public) dist

? Configure as a single-page app (rewrite all urls to /index.html)? (y/N) y

? File dist/index.html already exists. Overwrite? (y/N) y

Deployment

$ firebase deploy --only hosting

Icon is now added to home screen as well as Native Application. (Also the trouble of installing from AppStore was reduced)

Since static contents are cached, it works quickly. (Although API seems be able to cache too, but this time it is omitted)

PWA — Push Notifications

I use Firebase Cloud Messaging(FCM)for Push Notifications.

Ref. Set up a JavaScript Firebase Cloud Messaging client app | Firebase Ref. Receive messages in a JavaScript client | Firebase
Ref. Firebase Cloud Messaging Quickstart | GitHub

  1. Configure Web Credentials with FCM

  1. Add the gcm_sender_id in Web App Manifest
./public/manitest.json
{
  ...,
  "gcm_sender_id": "103953800507"
}
  1. Install Firebase SDK
$ npm install --save firebase
  1. Get Firebase Configuration


Step 1


Step 2


Step 3


Step 4


Step 5


Finish (Settings > General)

5. Request Permission of Notifications and Get Token

./src/main.ts
import * as firebase from "firebase";

var config = {
  apiKey: "xxxxxxxxxxxx",
  authDomain: "xxx.firebaseapp.com",
  databaseURL: "https://xxx.firebaseio.com",
  projectId: "xxx",
  storageBucket: "xxx.appspot.com",
  messagingSenderId: "xxxxxxxxxxxx"
}; // 4. Get Firebase Configuration
firebase.initializeApp(config);

const messaging = firebase.messaging();

messaging.usePublicVapidKey("xxxxxxx"); // 1. Generate a new key pair

// Request Permission of Notifications
messaging.requestPermission().then(() => {
  console.log('Notification permission granted.');

  // Get Token
  messaging.getToken().then((token) => {
    console.log(token)
  })
}).catch((err) => {
  console.log('Unable to get permission to notify.', err);
});

6. Add Service Worker for FCM

In order to receive the onMessage event, your app must define the Firebase messaging service worker in firebase-messaging-sw.js. Alternatively, you can specify an existing service worker with [useServiceWorker](https://firebase.google.com/docs/reference/js/firebase.messaging.Messaging?authuser=0#useServiceWorker).

./public/firebase-messaging-sw.js
// [START initialize_firebase_in_sw]
// Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here, other Firebase libraries
// are not available in the service worker.
importScripts('https://www.gstatic.com/firebasejs/5.5.6/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/5.5.6/firebase-messaging.js');
// Initialize the Firebase app in the service worker by passing in the messagingSenderId.
firebase.initializeApp({
  'messagingSenderId': 'xxxxxxxxx' // 4. Get Firebase Configuration
});

// Retrieve an instance of Firebase Messaging so that it can handle background messages.
const messaging = firebase.messaging();
// [END initialize_firebase_in_sw]

Because Push Notification needs that Service Worker is running, npm run build and access to localhost with Web Server for Chrome.


Request Permission


Get Token

7. Receive Test Message via cURL


Cloud Messaging > Server key

$ curl -X POST -H "Authorization: key=${The above server key}" -H "Content-Type: application/json" -d '{
  "to": "${5’s token}",
  "notification": {
    "title": "FCM Message",
    "body": "This is an FCM Message",
    "icon": "./img/icons/android-chrome-192x192.png"
  }
}' https://fcm.googleapis.com/fcm/send


Success


Not receive a message if target page is active


Permission dialog


Success


A notification dot is also attached to icon

Summary

By using PWA you can provide UX similar to Native application even with Web application.

Since there are things that I can not introduce this time, I will write again if I have the opportunity.

Service Workers

  • Cache Control
  • Offline Page

Push Notifications

  • Token Refresh
  • Firebase Cloud Messaging

Finally

I posted the original tutorial to my blog. If you feel this article is good, please react to it. Thank you.

Recommended Reading

Building a Simple Virtual DOM from Scratch

How to build a Ruby on Rails Application with Vue.js using JSX

5+ Vue.js Tricks You Should Know

How to build an application using Vue.js with Vuex state management

How to Create a Live Search Feature with Laravel and Vue.js

#vue-js #javascript

How to build PWA w/ Vue CLI 3
80.85 GEEK