{"record":{"id":"c0339ffedde5aff1","repo":"koala73/worldmonitor","slug":"web-push-is-not-supported-in-this-browser","errorCode":null,"errorMessage":"Web push is not supported in this browser.","messagePattern":"Web push is not supported in this browser\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/services/push-notifications.ts","lineNumber":130,"sourceCode":"  return fetch(path, {\n    ...init,\n    headers: {\n      'Content-Type': 'application/json',\n      ...(init.headers ?? {}),\n      Authorization: `Bearer ${token}`,\n    },\n  });\n}\n\n/**\n * Ask permission (if needed), subscribe via pushManager, and register\n * the endpoint with the server. Resolves with the payload the server\n * accepted, or throws on cancel / denial / network failure.\n */\nexport async function subscribeToPush(expectedUserId?: string): Promise<SubscriptionPayload> {\n  assertExpectedAccount(expectedUserId);\n  if (!isWebPushSupported()) {\n    throw new Error('Web push is not supported in this browser.');\n  }\n  const reg = await getRegistration();\n  if (!reg) throw new Error('Service worker unavailable.');\n\n  const perm = await Notification.requestPermission();\n  if (perm !== 'granted') {\n    throw new Error(\n      perm === 'denied'\n        ? 'Notifications are blocked. Enable them in your browser settings to continue.'\n        : 'Notifications permission was not granted.',\n    );\n  }\n\n  // Re-use an existing subscription if pushManager already has one\n  // for this origin. Re-registering via POST keeps server state in\n  // sync even when the browser has a stale subscription — this is\n  // important after sign-out/sign-in, where the browser's push\n  // identity persists but the Convex row does not.","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/koala73/worldmonitor/blob/eeab0a219fce0f02a00603b532dbae9041b934ac/src/services/push-notifications.ts#L112-L148","documentation":"Thrown by subscribeToPush() in src/services/push-notifications.ts when isWebPushSupported() returns false. That gate fails when: running inside a Tauri webview (__TAURI_INTERNALS__/__TAURI__ markers), navigator.serviceWorker is missing, window.PushManager is missing, Notification is undefined, or the build lacks a VAPID key (VITE_VAPID_PUBLIC_KEY unset — treated as unsupported on purpose so the cryptic pushManager error is avoided). The intended UX is an 'Install the app first / unsupported' hint, not an error.","triggerScenarios":"iOS Safari without Add to-Home-Screen (and all pre-16.4 iOS); in-app browsers (Instagram, LinkedIn, Facebook WebViews) that omit PushManager; Tauri desktop webview; builds where VITE_VAPID_PUBLIC_KEY was not injected; very old browsers without service worker support.","commonSituations":"Mobile users opening the site from social-app browsers; desktop users on the Tauri build expecting web push; QA on preview builds compiled without the VAPID env var; older Safari versions.","solutions":["Call isWebPushSupported() first and render a friendly 'not supported here — open in a regular browser / install the app' state.","On iOS, instruct users to Add to Home Screen (iOS 16.4+) and retry from the installed PWA.","If it fails everywhere including Chrome desktop, check that VITE_VAPID_PUBLIC_KEY was set at build time.","For the desktop app, route notifications through the Tauri app's mechanism instead of web push."],"exampleFix":"// before\nawait subscribeToPush(userId);\n\n// after\nimport { isWebPushSupported } from '@/services/push-notifications';\nif (!isWebPushSupported()) {\n  showNotice('Push notifications are not supported in this browser. Open the app in a standard browser or install it.');\n  return;\n}\nawait subscribeToPush(userId);","handlingStrategy":"validation","validationCode":"import { isWebPushSupported, getPushPermission } from '@/services/push-notifications';\n\nif (!isWebPushSupported()) {\n  renderUnsupportedNotice('Open the app in a standard browser, or install it on iOS 16.4+.');\n  return;\n}\nawait subscribeToPush(expectedUserId);","typeGuard":"function canAttemptWebPush(): boolean {\n  return typeof window !== 'undefined'\n    && 'serviceWorker' in navigator\n    && 'PushManager' in window\n    && typeof Notification !== 'undefined';\n}","tryCatchPattern":"try {\n  await subscribeToPush(expectedUserId);\n} catch (err) {\n  if (err instanceof Error && err.message === 'Web push is not supported in this browser.') {\n    renderUnsupportedNotice(); // capability gap — no retry will help\n    return;\n  }\n  throw err;\n}","preventionTips":["Always run isWebPushSupported() before showing push UI; the codebase intends this to route to an 'install the app' hint.","Remember builds without VITE_VAPID_PUBLIC_KEY are intentionally 'unsupported' — set the key in every environment.","For iOS, guide users through Add to Home Screen before enabling notifications."],"tags":["push-notifications","browser-support","ios-safari","tauri","feature-detection","vapid"],"backgroundTag":"unsupported-browser-feature","analyzedSha":"eeab0a219fce0f02a00603b532dbae9041b934ac","analyzedAt":"2026-08-21T16:51:25.751Z","contentChangedAt":"2026-08-21T16:51:25.751Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}