fix: service worker registration

This commit is contained in:
2026-05-08 19:23:13 +02:00
parent 68e16fa4ca
commit d3faf79b57
3 changed files with 36 additions and 4 deletions

1
web/src/app.d.ts vendored
View File

@@ -1,3 +1,4 @@
/// <reference types="vite-plugin-pwa/client" />
// See https://svelte.dev/docs/kit/types#app.d.ts // See https://svelte.dev/docs/kit/types#app.d.ts
// for information about these interfaces // for information about these interfaces
declare global { declare global {

View File

@@ -1,4 +1,5 @@
<script lang="ts"> <script lang="ts">
import { pwaInfo } from 'virtual:pwa-info';
import { page } from '$app/state'; import { page } from '$app/state';
import { hasToken } from '$lib/api/client'; import { hasToken } from '$lib/api/client';
import { onMount, onDestroy } from 'svelte'; import { onMount, onDestroy } from 'svelte';
@@ -8,7 +9,15 @@
let { children } = $props(); let { children } = $props();
onMount(() => { onMount(async () => {
// Register the PWA service worker through SvelteKit's pipeline.
// vite-plugin-pwa's injectRegister option cannot inject into SvelteKit's
// HTML because SvelteKit intercepts Vite's transformIndexHtml hook.
if (pwaInfo) {
const { registerSW } = await import('virtual:pwa-register');
registerSW({ immediate: true });
}
if (!hasToken() && page.url.pathname !== '/settings') { if (!hasToken() && page.url.pathname !== '/settings') {
goto('/settings'); goto('/settings');
} }
@@ -46,6 +55,12 @@
onDestroy(() => clearInterval(tickInterval)); onDestroy(() => clearInterval(tickInterval));
</script> </script>
<svelte:head>
{#if pwaInfo}
{@html pwaInfo.webManifest.linkTag}
{/if}
</svelte:head>
<nav> <nav>
<div class="nav-links"> <div class="nav-links">
<a href={todayHref()} class:active={todayActive}>Today</a> <a href={todayHref()} class:active={todayActive}>Today</a>

View File

@@ -2,16 +2,28 @@ import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vitest/config'; import { defineConfig } from 'vitest/config';
import { VitePWA } from 'vite-plugin-pwa'; import { VitePWA } from 'vite-plugin-pwa';
// A revision that changes on every build, so the SW always re-fetches index.html
// when the app is redeployed. index.html is not picked up by globPatterns because
// the static adapter creates it AFTER the service worker precache manifest is
// generated — so we add it explicitly here instead.
const buildId = Date.now().toString();
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [
sveltekit(), sveltekit(),
VitePWA({ VitePWA({
registerType: 'autoUpdate', registerType: 'autoUpdate',
strategies: 'generateSW', strategies: 'generateSW',
injectRegister: 'auto', injectRegister: false,
workbox: { workbox: {
globPatterns: ['**/*.{js,css,html,svg,png,ico,woff,woff2}'], globPatterns: ['**/*.{js,css,svg,png,ico,woff,woff2}'],
navigateFallback: 'index.html', additionalManifestEntries: [
{ url: '/', revision: buildId },
{ url: '/index.html', revision: buildId }
],
cleanupOutdatedCaches: true,
clientsClaim: true,
navigateFallback: '/index.html',
navigateFallbackDenylist: [/^\/api/, /^\/healthz/], navigateFallbackDenylist: [/^\/api/, /^\/healthz/],
runtimeCaching: [ runtimeCaching: [
{ {
@@ -25,6 +37,10 @@ export default defineConfig({
} }
] ]
}, },
devOptions: {
enabled: true,
type: 'module'
},
manifest: { manifest: {
name: 'Wotra — Working Time Tracker', name: 'Wotra — Working Time Tracker',
short_name: 'Wotra', short_name: 'Wotra',