vite-plugin-pwa
vite-plugin-pwa copied to clipboard
Failed to update a ServiceWorker for scope
I've been having countless errors of this sort:
Failed to update a ServiceWorker for scope ('https://www.kenmei.co/') with script ('https://www.kenmei.co/sw.js'): An unknown error occurred when fetching the script.

which appears as unhandled in Sentry, but it doesn't seem to be an actual issue on the site. While I could just ignore this error, I also want to understand why it happens, to make sure it's nothing more serious. I wasn't able to reproduce or even find an understand what is the cause for this error.
Update Prompt with SW registration
<script setup>
import { useRegisterSW } from 'virtual:pwa-register/vue';
const intervalMS = 1800000; // 30 minutes in milliseconds
/* eslint-disable no-unused-vars */
const { needRefresh, updateServiceWorker } = useRegisterSW({
immediate: true,
onRegistered(r) {
// eslint-disable-next-line no-unused-expressions
r && setInterval(() => { r.update(); }, intervalMS);
},
});
const close = async () => { needRefresh.value = false; };
const updateWorker = async () => {
close();
updateServiceWorker();
};
/* eslint-enable */
</script>
<template lang="pug">
.prompt(aria-live='assertive')
.w-full.flex.flex-col.items-center.space-y-4.sm_items-end
transition(
enter-active-class='transform ease-out duration-300 transition'
enter-from-class='translate-y-2 opacity-0 sm_translate-y-0 sm_translate-x-2'
enter-to-class='translate-y-0 opacity-100 sm_translate-x-0'
leave-active-class='transition ease-in duration-100'
leave-from-class='opacity-100'
leave-to-class='opacity-0'
)
.prompt-wrapper(v-if="needRefresh")
.p-4
.flex.items-start
.flex-shrink-0
icon-download-outline.icon(aria-hidden='true')
.ml-3.w-0.flex-1.-mt-1
p.text-sm.text-gray-500.dark_text-white
| New app update is available. Update to get the newest
| features and improvements.
.mt-3.flex.space-x-7
button.button--primary(
v-if='needRefresh'
type='button'
@click="updateWorker"
)
| Update
button.button--secondary(type='button' @click='close')
| Close
</template>
<style lang="scss" scoped>
button {
@apply bg-white rounded-md text-sm font-medium;
@apply focus_outline-none focus_ring-2 focus_ring-offset-2;
@apply focus_ring-blue-500;
@apply dark_bg-transparent;
}
.button--primary {
@apply text-blue-600 hover_text-blue-500;
@apply dark_text-blue-500 dark_hover_text-blue-400;
}
.button--secondary {
@apply text-gray-700 hover_text-gray-500;
@apply dark_text-white dark_hover_text-gray-200;
}
.prompt {
@apply fixed inset-x-0 top-0 flex items-end px-4 py-6 pointer-events-none;
@apply z-50;
@apply sm_p-6 sm_items-start;
}
.icon {
@apply h-6 w-6 text-green-400;
@apply dark_opacity-90;
}
.prompt-wrapper {
@apply max-w-sm w-full bg-white shadow-lg rounded-lg pointer-events-auto;
@apply ring-1 ring-black ring-opacity-5 overflow-hidden;
@apply dark_bg-gray-700;
}
</style>
Vite Config
import path from 'path';
import { defineConfig, splitVendorChunkPlugin } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueI18n from '@intlify/vite-plugin-vue-i18n';
import { VitePWA } from 'vite-plugin-pwa';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
splitVendorChunkPlugin(),
vueI18n({
include: path.resolve(__dirname, './src/locales/**'),
}),
VitePWA({
includeAssets: ['favicon.ico', 'robots.txt', 'apple-icon-180.png'],
workbox: {
globPatterns: [
// all packaged resources are stored here
'assets/*',
// add HTML and other resources for the root directory
'*.{svg,png,jpg}',
'*.html',
'manifest.webmanifest',
],
},
manifest: {
short_name: 'Kenmei',
name: 'Kenmei | Cross-site manga tracker',
icons: [
{
src: 'any_icon_x192.png',
sizes: '192x192',
type: 'image/png',
purpose: 'any',
},
{
src: 'maskable_icon_x192.png',
sizes: '192x192',
type: 'image/png',
purpose: 'maskable',
},
{
src: 'any_icon_x384.png',
sizes: '384x384',
type: 'image/png',
purpose: 'any',
},
{
src: 'maskable_icon_x384.png',
sizes: '384x384',
type: 'image/png',
purpose: 'maskable',
},
{
src: 'any_icon_x512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any',
},
{
src: 'maskable_icon_x512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'maskable',
},
{
src: 'any_icon.png',
sizes: '1024x1024',
type: 'image/png',
purpose: 'any',
},
{
src: 'maskable_icon.png',
sizes: '1024x1024',
type: 'image/png',
purpose: 'maskable',
},
],
start_url: '/dashboard',
background_color: '#FFFFFF',
display: 'standalone',
scope: '/',
theme_color: '#FFFFFF',
description: 'Cross-site manga tracker, that lets you read and track manga across websites',
},
}),
],
server: {
port: 8080,
},
build: {
sourcemap: true,
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
});
The SW itself works fine and updates without issues, so right now these errors just seem to be noise. There are also some similar errors that I can observe:
Failed to update a ServiceWorker for scope ('https://www.kenmei.co/') with script ('https://www.kenmei.co/sw.js'): A bad HTTP response code (504) was received when fetching the script.AbortError: Failed to update a ServiceWorker for scope ('https://www.kenmei.co/') with script ('Unknown'): The Service Worker system has shutdown.Failed to update a ServiceWorker: An unknown error occurred when fetching the script.AbortError: Failed to update a ServiceWorker for scope ('https://www.kenmei.co/') with script ('https://www.kenmei.co/sw.js'): The Service Worker system has shutdown.Failed to update a ServiceWorker for scope ('https://www.kenmei.co/') with script ('https://www.kenmei.co/sw.js'): A bad HTTP response code (400) was received when fetching the script.Failed to update a ServiceWorker for scope ('https://www.kenmei.co/') with script ('https://www.kenmei.co/sw.js'): A bad HTTP response code (403) was received when fetching the script.
@doutatsu what browser is complaining? On Windows Chrome is ok: try to include id: '/' in the manifest.



All of them - but 71% is Chrome / Chrome Mobile, followed by Safari, Edge Firefox. I'll try the fix you are suggesting 👀
For context - this seems to be a good explanation on the ID in the manifest: https://developer.chrome.com/blog/pwa-manifest-id/
@doutatsu try chaning the start_url: './dashboard':
- https://developer.mozilla.org/en-US/docs/Web/Manifest/start_url
- https://web.dev/learn/pwa/enhancements/#app-shortcuts

@doutatsu also working on Android 9 Tablet with Chrome (screenshot using USB degugger):

@userquin as mentioned - the worker is working, there are no issues there. It's just this error that happens for some reason. I've deployed the ID, so will be monitoring whatever the error comes back or not
Unfortunately the ID change did nothing - still getting the error and rate doesn't seem to have changed
@doutatsu file an issue in workbox repo, maybe Jeff can help you.
Try removing the start url or using Just dashboard or ./dashboard (relative to the scope).
@userquin I've had the same error when I was triggering updates manually:
(await navigator.serviceWorker.getRegistration()).update()
Adding same scope: '/' option as in manifest fixed the issue
In my opinion it should not be necessary, as it should be inherited from vitejs base option
https://github.com/antfu/vite-plugin-pwa/blob/368542e6c1069f07f4d45969a948919765297258/src/types.ts#L44-L49
...which defaults to /
reference: vitejs docs Shared Options > base
@piotr-cz It didn't work out for me - I had the scope set to / and I am still seeing this error
@doutatsu maybe you can try this approach: https://github.com/antfu/vite-plugin-pwa/issues/366#issuecomment-1235780068
Keeping logs on the progress to address this issue in here - https://github.com/antfu/vite-plugin-pwa/issues/366