diff --git a/.changeset/thin-horses-bake.md b/.changeset/thin-horses-bake.md
new file mode 100644
index 00000000000..bd9d2bcde02
--- /dev/null
+++ b/.changeset/thin-horses-bake.md
@@ -0,0 +1,7 @@
+---
+'@builder.io/qwik-city': patch
+---
+
+FIX: Your service-worker.js won't be unregistered anymore if you added custom logic to it.
+
+> Note: Qwik 1.14.0 and above now use `` by default. If you didn't add custom service-worker logic, you should remove your service-worker.ts file(s) for the `ServiceWorkerRegister` Component to actually unregister the service-worker.js and delete its related cache. Make sure to keep the `ServiceWorkerRegister` Component in your app (without any service-worker.ts file) as long as you want to unregister the service-worker.js for your users.
diff --git a/packages/qwik-city/src/buildtime/runtime-generation/generate-service-worker.ts b/packages/qwik-city/src/buildtime/runtime-generation/generate-service-worker.ts
index 1f9209a43ce..5f291122507 100644
--- a/packages/qwik-city/src/buildtime/runtime-generation/generate-service-worker.ts
+++ b/packages/qwik-city/src/buildtime/runtime-generation/generate-service-worker.ts
@@ -2,30 +2,48 @@ import type { BuildContext } from '../types';
export function generateServiceWorkerRegister(ctx: BuildContext, swRegister: string) {
let swReg: string;
+ let swUrl = '/service-worker.js';
- if (ctx.isDevServer) {
+ // Also unregister if the developer removed the service-worker.ts file since Qwik 1.14.0 and above now use modulepreload by default
+ if (ctx.isDevServer || ctx.serviceWorkers.length === 0) {
swReg = SW_UNREGISTER;
} else {
swReg = swRegister;
- let swUrl = '/service-worker.js';
- if (ctx.serviceWorkers.length > 0) {
- const sw = ctx.serviceWorkers.sort((a, b) =>
- a.chunkFileName.length < b.chunkFileName.length ? -1 : 1
- )[0];
- swUrl = ctx.opts.basePathname + sw.chunkFileName;
- }
-
- swReg = swReg.replace('__url', swUrl);
+ const sw = ctx.serviceWorkers.sort((a, b) =>
+ a.chunkFileName.length < b.chunkFileName.length ? -1 : 1
+ )[0];
+ swUrl = ctx.opts.basePathname + sw.chunkFileName;
}
+ swReg = swReg.replace('__url', swUrl);
return `export default ${JSON.stringify(swReg)};`;
}
const SW_UNREGISTER = `
-navigator.serviceWorker?.getRegistrations().then((regs) => {
- for (const reg of regs) {
- reg.unregister();
- }
-});
+"serviceWorker"in navigator&&navigator.serviceWorker.getRegistrations().then(r=>{for(const e of r){const c='__url'.split("/").pop();e.active?.scriptURL.endsWith(c||"service-worker.js")&&e.unregister().catch(console.error)}}),"caches"in window&&caches.keys().then(r=>{const e=r.find(c=>c.startsWith("QwikBuild"));e&&caches.delete(e).catch(console.error)}).catch(console.error)
`;
+// Code in SW_UNREGISTER unregisters the service worker and deletes the cache; it is the minified version of the following:
+// (() => {
+// if ('serviceWorker' in navigator) {
+// navigator.serviceWorker.getRegistrations().then((regs) => {
+// for (const reg of regs) {
+// const url = '__url'.split('/').pop();
+// if (reg.active?.scriptURL.endsWith(url || 'service-worker.js')) {
+// reg.unregister().catch(console.error);
+// }
+// }
+// });
+// }
+// if ('caches' in window) {
+// caches
+// .keys()
+// .then((names) => {
+// const cacheName = names.find((name) => name.startsWith('QwikBuild'));
+// if (cacheName) {
+// caches.delete(cacheName).catch(console.error);
+// }
+// })
+// .catch(console.error);
+// }
+// })();
diff --git a/packages/qwik-city/src/buildtime/vite/plugin.ts b/packages/qwik-city/src/buildtime/vite/plugin.ts
index 880e5d22a9c..e9d0d2ae287 100644
--- a/packages/qwik-city/src/buildtime/vite/plugin.ts
+++ b/packages/qwik-city/src/buildtime/vite/plugin.ts
@@ -191,6 +191,7 @@ function qwikCityPlugin(userOpts?: QwikCityVitePluginOptions): any {
}
}
}
+
return null;
},
diff --git a/packages/qwik-city/src/runtime/src/sw-component.tsx b/packages/qwik-city/src/runtime/src/sw-component.tsx
index 2aa9bbd8c0c..8b020818708 100644
--- a/packages/qwik-city/src/runtime/src/sw-component.tsx
+++ b/packages/qwik-city/src/runtime/src/sw-component.tsx
@@ -5,6 +5,12 @@ import type { JSXOutput } from '@builder.io/qwik';
* JS extensions are allowed) will be picked up, bundled into a separate file, and registered as a
* service worker.
*
+ * Qwik 1.14.0 and above now use `` by default. If you didn't add custom
+ * service-worker logic, you should remove your service-worker.ts file(s) for the
+ * `ServiceWorkerRegister` Component to actually unregister the service-worker.js and delete its
+ * related cache. Make sure to keep the `ServiceWorkerRegister` Component in your app (without any
+ * service-worker.ts file) as long as you want to unregister the service-worker.js for your users.
+ *
* @public
*/
export const ServiceWorkerRegister = (props: { nonce?: string }): JSXOutput => (
diff --git a/packages/qwik-city/src/runtime/src/sw-register.ts b/packages/qwik-city/src/runtime/src/sw-register.ts
index 8df878bc83c..89b19fecefa 100644
--- a/packages/qwik-city/src/runtime/src/sw-register.ts
+++ b/packages/qwik-city/src/runtime/src/sw-register.ts
@@ -2,24 +2,21 @@
(() => {
if ('serviceWorker' in navigator) {
- navigator.serviceWorker.getRegistrations().then((regs) => {
- for (const reg of regs) {
- const url = '__url'.split('/').pop();
- if (reg.active?.scriptURL.endsWith(url || 'service-worker.js')) {
- reg.unregister().catch(console.error);
- }
- }
- });
- }
- if ('caches' in window) {
- caches
- .keys()
- .then((names) => {
- const cacheName = names.find((name) => name.startsWith('QwikBuild'));
- if (cacheName) {
- caches.delete(cacheName).catch(console.error);
- }
- })
- .catch(console.error);
+ navigator.serviceWorker.register('__url').catch((e) => console.error(e));
+ // We need to delete the cache since we are using modulepreload by default in qwik 1.14 and above
+ if ('caches' in window) {
+ caches
+ .keys()
+ .then((names) => {
+ const cacheName = names.find((name) => name.startsWith('QwikBuild'));
+ if (cacheName) {
+ caches.delete(cacheName).catch(console.error);
+ }
+ })
+ .catch(console.error);
+ }
+ } else {
+ // eslint-disable-next-line no-console
+ console.log('Service worker not supported in this browser.');
}
})();