Can't add Vue.js PWA to homescreen

5.2k views Asked by At

I'm diving into Progressive Web Applications lately. I've linked my manifest.json and sw.js like this:

In the index.html

<link rel="manifest" href="<%= htmlWebpackPlugin.files.publicPath %>static/manifest.json">

And in my main.js

if('serviceWorker' in navigator) {
        const messaging = firebase.messaging()

        navigator.serviceWorker.register('/static/sw.js').then((registration) => {
            messaging.useServiceWorker(registration)
            console.log('Service Worker registered')
        }).catch((error) => {
            console.log('Service Worker failed to register')
        })
    }

It looks like it works, but when I try to add the webapp to my homescreen using DevTools, it shows the following error: "Site cannot be installed: no matching service worker detected. You may need to reload the page, or check that the service worker for the current page also controls the start URL from the manifest"

After doing some research I found people say place the sw.js and manifest.json in the root of the project. But when I do, it won't link the files (when I put them in the static folder, it will link them). By the way, I'm using the standard Vue.js template.

Any suggestions how to fix this?

1

There are 1 answers

5
Arielle Nguyen On

The reason to the service worker failed to register could be 1 of these:

  1. You are not running your application through HTTPS.
  2. The path to your service worker file is not written correctly — it needs to be written relative to the origin, not your app’s root directory.

Structure wise, it should be like this

/static/
    /css/
    /js/
    /img/
manifest.json
index.html
service-worker.js

In the index file, you should register the service worker similar to this

<script type=text/javascript>
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/service-worker.js')
    .then(function(registration) {
      console.log('Registration successful, scope is:', registration.scope);
    })
    .catch(function(error) {
      console.log('Service worker registration failed, error:', error);
    });
  }
</script>

and connect manifest.json

<link rel=manifest href=/manifest.json>

Content of manifest.json can be

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

sw-precache is designed specifically for the needs of precaching some critical static resources. So if you want to do something else with service worker when user is offline, you don't need it. Here is an example list of what you can do with service workers: https://github.com/GoogleChrome/samples/tree/gh-pages/service-worker