From 4753216b5666a89711bb37dcc141db8c472c2d58 Mon Sep 17 00:00:00 2001 From: Gemini Agent Date: Fri, 23 Jan 2026 21:00:39 +0000 Subject: [PATCH] Fix service worker registration for push notifications Instead of waiting on navigator.serviceWorker.ready (which may never resolve if registration hasn't completed), explicitly register the service worker and wait for it to activate. This fixes the "service worker not ready" error on iOS Safari PWAs. Co-Authored-By: Claude Opus 4.5 --- .../notifications/NotificationPermission.tsx | 39 ++++++++++++++++--- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/components/notifications/NotificationPermission.tsx b/src/components/notifications/NotificationPermission.tsx index da21290..f4358d5 100644 --- a/src/components/notifications/NotificationPermission.tsx +++ b/src/components/notifications/NotificationPermission.tsx @@ -79,12 +79,39 @@ export function NotificationPermission({ workspaceId }: NotificationPermissionPr } const { publicKey } = await keyResponse.json() - // Wait for service worker with timeout - const registrationPromise = navigator.serviceWorker.ready - const timeoutPromise = new Promise((_, reject) => - setTimeout(() => reject(new Error('Service worker not ready - try refreshing the page')), 10000) - ) - const registration = await Promise.race([registrationPromise, timeoutPromise]) + // Ensure service worker is registered and active + let registration: ServiceWorkerRegistration + + // First, try to register the service worker (in case it wasn't registered yet) + try { + registration = await navigator.serviceWorker.register('/sw.js', { scope: '/' }) + + // Wait for it to be active + if (registration.installing || registration.waiting) { + await new Promise((resolve, reject) => { + const sw = registration.installing || registration.waiting + if (!sw) { + resolve() + return + } + + const timeout = setTimeout(() => reject(new Error('Service worker activation timeout')), 10000) + + sw.addEventListener('statechange', () => { + if (sw.state === 'activated') { + clearTimeout(timeout) + resolve() + } else if (sw.state === 'redundant') { + clearTimeout(timeout) + reject(new Error('Service worker became redundant')) + } + }) + }) + } + } catch (regError: any) { + console.error('Service worker registration error:', regError) + throw new Error('Failed to register service worker: ' + regError.message) + } // Check if push manager is available if (!registration.pushManager) {