Skip to content

Instantly share code, notes, and snippets.

@DRBragg
Last active May 14, 2020 16:57
Show Gist options
  • Save DRBragg/2b6154c583a36cd2019a27afd5e227d3 to your computer and use it in GitHub Desktop.
Save DRBragg/2b6154c583a36cd2019a27afd5e227d3 to your computer and use it in GitHub Desktop.
SW Content Update (Vue)
// src/App.vue
// I use Vuetify in almost all of my Vue apps so this is how __I__ handle alerting the user to an update.
// Your implementation may change based on your UI
<template>
<!-- normal vue views stuff -->
<v-snackbar bottom right :value="updateExists" :timeout="0" color="primary">
An update is available
<v-btn text @click="refreshApp">
Update
</v-btn>
</v-snackbar>
</template>
<script>
import update from './mixins/update'
export default {
name: 'App',
data: () => ({
//
}),
mixins: [update],
...
}
</script>
// src/registerServiceWorker.js
// Standard SW registration script.
// Auto generated by the Vue CLI PWA Plugin
import { register } from 'register-service-worker'
if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
...
// When the SW is updated we will dispacth an event we can listen to in our .vue file
updated(registration) {
console.log('New content is available; please refresh.')
document.dispatchEvent(
new CustomEvent('swUpdated', { detail: registration })
)
},
...
})
}
// src/service-worker.js
// If you are using 'GenerateSW' (default) for your workboxPluginMode setting this file is auto generated for you.
// If you are using 'InjectManifest' then add this to your custom SW after your standard workbox config
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting()
}
})
// src/mixins/update.js
export default {
data() {
return {
// refresh variables
refreshing: false,
registration: null,
updateExists: false,
}
},
created() {
// Listen for our custom event from the SW registration
document.addEventListener('swUpdated', this.showRefreshUI, { once: true })
// Prevent multiple refreshes
navigator.serviceWorker.addEventListener('controllerchange', () => {
if (this.refreshing) return
this.refreshing = true
// Here the actual reload of the page occurs
window.location.reload()
})
},
methods: {
// Store the SW registration so we can send it a message
// We use `updateExists` to control whatever alert, toast, dialog, etc we want to use
// To alert the user there is an update they need to refresh for
showRefreshUI(e) {
this.registration = e.detail
this.updateExists = true
},
// Called when the user accepts the update
refreshApp() {
this.updateExists = false
// Make sure we only send a 'skip waiting' message if the SW is waiting
if (!this.registration || !this.registration.waiting) return
// send message to SW to skip the waiting and activate the new SW
this.registration.waiting.postMessage({ type: 'SKIP_WAITING' })
},
},
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment