Para implementar una Progressive Web App (PWA) con Vue.js, sigue los siguientes pasos:

Instala @vue/cli-plugin-pwa

Cuando instalas el paquete @vue/cli-plugin-pwa, una de las funcionalidades que proporciona es la generación automática de los iconos de la PWA, que se utilizan en diferentes plataformas y dispositivos, como la pantalla de inicio de un dispositivo móvil o la barra de tareas de un sistema operativo.

La carpeta de icons se crea en la carpeta public del proyecto de Vue.js, y los iconos generados se basan en una sola imagen que proporcionas en la configuración del PWA.

Se creará un archivo 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(
        '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)
    }
  })
}

Importar archivo en main.js

import './registerServiceWorker'

Si deseas utilizar el archivo registerServiceWorker.js, asegúrate de que su contenido sea el adecuado y que el Service Worker (service-worker.js) esté presente en la ruta especificada. Si prefieres utilizar la configuración de Workbox, no es necesario utilizar registerServiceWorker.js, y debes asegurarte de que vue.config.js esté correctamente configurado para generar y registrar el Service Worker.

en el archivo vue.config

module.exports = {
    pwa: {
        name: "My App",
        themeColor: "#1f4d9d", // Color de tema
        msTileColor: "#000000", // Color para la barra de tareas de Windows
        appleMobileWebAppCapable: "yes", // Habilitar modo de aplicación en dispositivos Apple
        appleMobileWebAppStatusBarStyle: "black", // Estilo de la barra de estado en dispositivos Apple
    
        // Configuración del Service Worker
        manifestPath: "manifest.json",
        workboxPluginMode: "GenerateSW",
        workboxOptions: {
          skipWaiting: true,
          clientsClaim: true,
          exclude: [/\.map$/, /_redirects/],
    
          // Estrategias de caché personalizadas
          runtimeCaching: [
            {
                urlPattern: new RegExp("^https://api.com/api/"),
                handler: "NetworkFirst",
                options: {
                  cacheName: "api-cache",
                  networkTimeoutSeconds: 10,
                },
            },
            {
                urlPattern: /\.(png|jpg|jpeg|svg)$/,
                handler: "CacheFirst", // Estrategia de caché: Intenta la caché y usa la red si no está disponible.
                options: {
                  cacheName: "images-cache",
                  expiration: {
                    maxEntries: 200, // Número máximo de elementos en caché
                    maxAgeSeconds: 7 * 24 * 60 * 60, // 7 días
                  },
                },
            },

            {
                urlPattern: /\.(css|js)$/,
                handler: "StaleWhileRevalidate", // Estrategia de caché: Usa la caché, pero también verifica si hay una versión más nueva en la red.
                options: {
                  cacheName: "static-resources-cache",
                  expiration: {
                    maxEntries: 50,
                    maxAgeSeconds: 30 * 24 * 60 * 60, // 30 días
                  },
                },
            },
          ],
        },

        iconPaths: {
            favicon32: "img/icons/favicon-32x32.png",
            favicon16: "img/icons/favicon-16x16.png",
            appleTouchIcon: "img/icons/apple-touch-icon-152x152.png",
            maskIcon: "img/icons/safari-pinned-tab.svg",
            msTileImage: "img/icons/mstile-150x150.png",
        },

        manifestOptions: {
            display: "standalone",
            background_color: "#ffffff",
            orientation: "portrait",
        }
      },
}