Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PWA - Frontend doesn't update even after a hard refresh

  • Below is the configuration of our nuxt and nuxt-pwa configuration.
  • Nuxt pwa is recognising a new version available and we prompt user to do a hard refresh/reload.
  • And on reload - new UI also starts to work.
  • However, if we open the site in a new tab. A spinner gets shown & the latest frontend fails to load. And again, a hard refresh is required.
    • our frontend redirects to /dashboard on visiting localhost:8080 by default and this is getting loaded from serviceworker with cached data.
    • Please help us resolve this since this has been a critical issue for us.

Screenshot 2021-12-07 at 10 04 35

Spinner seen on new tab opening : Screenshot 2021-12-07 at 10 01 47

Screenshot 2021-12-07 at 10 01 40


export default {
  ssr: false,
  target: 'static',
  head: {
    titleTemplate: '',
    title: 'NocoDB',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: process.env.npm_package_description || '' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: './favicon-32.png' }
    ]
  },
  plugins: [
    // plugins
  ],
  buildModules: [
    '@nuxtjs/vuetify',
    '@nuxtjs/pwa'
  ],
  modules: [
    // Doc: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios',
    'vue-github-buttons/nuxt',
    '@nuxtjs/toast'
  ],
  axios: {
    baseURL: process.env.NC_BACKEND_URL || (process.env.NODE_ENV === 'production' ? '..' : 'http://localhost:8080')
  },
  router: {
    mode: 'hash',
    base: process.env.NODE_ENV === 'production' ? './' : '',
    middleware: ['auth']
  },
  vuetify: {
    defaultAssets: {
      icons: false
    },
    optionsPath: '@/config/vuetify.options.js',
    treeShake: true,
    customVariables: ['./config/variables.scss']
  },
  build: {
    parallel: true,
    plugins: [
      new MonacoEditorWebpackPlugin({
        languages: ['sql', 'json', 'javascript'],
        features: ['!gotoSymbol']
      })
    ],
    extend(config, { isDev, isClient }) {
      if (isDev) {
        config.devtool = isClient ? 'source-map' : 'inline-source-map'
      }

      config.externals = config.externals || {}
      config.externals['@microsoft/typescript-etw'] = 'FakeModule'
      return config
    }
  },
  pwa: {
    workbox: {
      assetsURLPattern: /\/_nuxt\//,
      config: { debug: true }
    },

    icon: { 
      publicPath: './' 
    },
    manifest: {
      name: 'NocoDB',
      start_url: '../?standalone=true',
      theme_color: '#ffffff'
    }
  }
}

Lighthouse report : Screenshot 2021-12-07 at 10 00 00

Github issue reference : https://github.com/nuxt-community/pwa-module/issues/501

like image 680
Pranav C Balan Avatar asked Oct 15 '22 19:10

Pranav C Balan


1 Answers

You need to set service worker which clears cache based on versions. Setup service-worker.js as below. and update LATEST_VERSION on changes you deploy.

// service-worker.js
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");

workbox.core.setCacheNameDetails({ prefix: 'pwa' })
//Change this value every time before you build to update cache
const LATEST_VERSION = 'v1.0.1'

self.addEventListener('activate', (event) => {
  console.log(`%c ${LATEST_VERSION} `, 'background: #ddd; color: #0000ff')
  if (caches) {
    caches.keys().then((arr) => {
      arr.forEach((key) => {
        if (key.indexOf('pwa-precache') < -1) {
          caches.delete(key).then(() => console.log(`%c Cleared ${key}`, 'background: #333; color: #ff0000'))
        } else {
          caches.open(key).then((cache) => {
            cache.match('version').then((res) => {
              if (!res) {
                cache.put('version', new Response(LATEST_VERSION, { status: 200, statusText: LATEST_VERSION }))
              } else if (res.statusText !== LATEST_VERSION) {
                caches.delete(key).then(() => console.log(`%c Cleared Cache ${LATEST_VERSION}`, 'background: #333; color: #ff0000'))
              } else console.log(`%c Great you have the latest version ${LATEST_VERSION}`, 'background: #333; color: #00ff00')
            })
          })
        }
      })
    })
  }
})

workbox.core.skipWaiting();
workbox.core.clientsClaim();

self.__precacheManifest = [].concat(self.__precacheManifest || [])
// workbox.precaching.suppressWarnings()
workbox.precaching.precacheAndRoute(self.__precacheManifest, {})
like image 166
Dipten Avatar answered Oct 28 '22 16:10

Dipten