Home » Building Progressive Web Apps (PWAs) with Vue

Progressive Web Apps (PWAs) have been revolutionizing the web by blending the best of web and mobile applications. These apps deliver a smooth, app-like experience on the web while being fast, reliable, and engaging. Vue.js, a progressive JavaScript framework, is an excellent choice for building PWAs due to its simplicity, flexibility, and robust community support.

In this guide, we’ll walk you through creating a PWA using Vue.js. We’ll cover the fundamental concepts, the tools you need, and a step-by-step guide to building and deploying a Vue-based PWA. By the end, you’ll have a solid understanding of how to create and deploy your own Vue-based PWA.

Getting Started with Vue and PWA

Prerequisites

Before you start, make sure you have the following installed on your machine:

  • Node.js (LTS version recommended)
  • Vue CLI (Command Line Interface)

Setting Up a New Vue Project

To create a new Vue project, open your terminal and run:

npm install -g @vue/cli
vue create my-pwa-app

When prompted to select features for your project, choose the default preset or manually select features for more control. Be sure to include the “PWA Support” option.

Adding PWA Support to an Existing Vue Project

If you already have an existing Vue project and want to add PWA support, you can do so by installing the Vue PWA plugin:

vue add pwa

This command adds the necessary files and configurations to turn your Vue application into a PWA.

Understanding the PWA Configuration

Running the ‘vue add pwa’ command creates a few important files in your project:

  • ‘public/manifest.json’
  • ‘src/registerServiceWorker.js’

Manifest File

The ‘manifest.json’ file contains metadata about your app. This includes details like the app’s name, icons, theme colors, and display mode. Here is a sample ‘manifest.json’:

{
  "name": "My PWA App",
  "short_name": "PWA",
  "theme_color": "#4DBA87",
  "background_color": "#000000",
  "display": "standalone",
  "scope": "/",
  "start_url": "/",
  "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"
    }
  ]
}

This file guides the browser on how to behave when your app is installed on a user’s device.

Service Worker

The ‘registerServiceWorker.js’ file is where the service worker is registered. A service worker is a script that your browser runs in the background, separate from a web page, opening the door to features like push notifications and background sync.

Here is a simplified version of ‘registerServiceWorker.js’:

import { register } from 'register-service-worker';

if (process.env.NODE_ENV === 'production') {
  register(`${process.env.BASE_URL}service-worker.js`, {
    ready() {
      console.log('Service worker is active.');
    },
    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);
    }
  });
}

Building Your PWA

With the basic setup out of the way, let’s build a simple PWA using Vue. We’ll create a weather application that fetches weather data and works offline.

Step 1: Create a Basic Vue Component

Create a new component called ‘Weather.vue’ in the ‘src/components’ directory:

<template>
  <div class="weather">
    <h1>Weather App</h1>
    <div v-if="weather">
      <h2>{{ weather.name }}</h2>
      <p>{{ weather.main.temp }}°C</p>
      <p>{{ weather.weather[0].description }}</p>
    </div>
    <button @click="fetchWeather">Get Weather</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      weather: null
    };
  },
  methods: {
    async fetchWeather() {
      try {
        const response = await fetch(
          'https://api.openweathermap.org/data/2.5/weather?q=London&appid=YOUR_API_KEY&units=metric'
        );
        this.weather = await response.json();
      } catch (error) {
        console.error('Error fetching weather data:', error);
      }
    }
  }
};
</script>

<style scoped>
.weather {
  text-align: center;
}
</style>

Replace ‘YOUR_API_KEY’ with your OpenWeatherMap API key. This component fetches and displays weather data for London when the button is clicked.

Step 2: Register the Component

Open ‘src/App.vue’ and register the ‘Weather’ component:


<template>
  <div id="app">
    <Weather />
  </div>
</template>

<script>
import Weather from './components/Weather.vue';

export default {
  name: 'App',
  components: {
    Weather
  }
};
</script>

<style>
/* Add your global styles here */
</style>

Step 3: Handle Offline Functionality

To make the app work offline, we need to cache the weather data.

Update the service worker in 'public/service-worker.js‘ to cache the API response:

self.addEventListener('fetch', function(event) {
  if (event.request.url.includes('api.openweathermap.org')) {
    event.respondWith(
      caches.open('weather-cache').then(function(cache) {
        return fetch(event.request)
          .then(function(response) {
            cache.put(event.request.url, response.clone());
            return response;
          })
          .catch(function() {
            return caches.match(event.request);
          });
      })
    );
  } else {
    event.respondWith(
      caches.match(event.request).then(function(response) {
        return response || fetch(event.request);
      })
    );
  }
});

This service worker intercepts network requests and caches the weather data. If the network is unavailable, it serves the cached data.

Step 4: Customize the App Manifest

Customize your ‘manifest.json’ to improve the appearance and behavior of your app:’

{
  "name": "Weather PWA",
  "short_name": "Weather",
  "theme_color": "#4DBA87",
  "background_color": "#000000",
  "display": "standalone",
  "scope": "/",
  "start_url": "/",
  "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"
    }
  ]
}

Step 5: Test Your PWA

To test your PWA, run the development server:

npm run serve

Open your browser and navigate to ‘http://localhost:8080’. You should see your weather app. To test the offline functionality, disable your internet connection and reload the page. If everything is set up correctly, the cached weather data should be displayed.

Advanced Features

Push Notifications

To implement push notifications, you’ll need to use a service like Firebase Cloud Messaging (FCM). Here’s a brief overview of how to integrate FCM with your Vue PWA:

1.Set up Firebase Project: Create a new project on the Firebase console and enable Cloud Messaging.

2.Install Firebase SDK:

npm install firebase

3.Initialize Firebase in Your Project:

// src/firebase.js
import firebase from 'firebase/app';
import 'firebase/messaging';

const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID"
};

firebase.initializeApp(firebaseConfig);

const messaging = firebase.messaging();

export { messaging };

4. Request Notification Permission:

// src/registerServiceWorker.js
import { messaging } from './firebase';

messaging.requestPermission()
  .then(() => {
    console.log('Notification permission granted.');
    return messaging.getToken();
  })
  .then((token) => {
    console.log('FCM Token:', token);
    // Send the token to your server and save it for later use
  })
  .catch((error) => {
    console.error('Error getting permission for notifications:', error);
  });

5.Handle Incoming Messages:

// src/firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/9.0.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/9.0.0/firebase-messaging.js');

firebase.initializeApp({ 
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID"
});

const messaging = firebase.messaging();

messaging.onBackgroundMessage((payload) => {
  console.log('[firebase-messaging-sw.js] Received background message ', payload);
  // Customize notification here
  const notificationTitle = 'Background Message Title';
  const notificationOptions = {
    body: 'Background Message body.',
    icon: '/firebase-logo.png'
  };

  self.registration.showNotification(notificationTitle, notificationOptions);
});

6.Update ‘vue.config.js’:

// vue.config.js
module.exports = {
  pwa: {
    workboxOptions: {
      importScripts: ['firebase-messaging-sw.js']
    }
  }
};

Deploying Your PWA

To deploy your PWA, you can use various platforms like Netlify, Vercel, or GitHub Pages. Here’s how to deploy your Vue PWA on Netlify:

  1. Build the Project:
npm run build

Deploy to Netlify:

  • Go to the Netlify website and sign in.
  • Click on “New site from Git”.
  • Connect your Git repository.
  • Set the build command to ‘npm run build’ and the publish directory to ‘dist’.
  • Deploy the site.

Conclusion

Building a PWA with Vue is a straightforward process that can significantly enhance the user experience of your web application. By leveraging the capabilities of PWAs, you can provide a fast, reliable, and engaging app that works offline and offers push notifications.

In this article, we’ve covered the basics of setting up a Vue project with PWA support, creating a simple weather app, and implementing offline functionality and push notifications. We’ve also touched on deployment strategies to get your PWA into the hands of users.

With these tools and knowledge, you’re well-equipped to start building powerful PWAs with Vue. Happy coding!

Leave a Reply

Your email address will not be published. Required fields are marked *