Fix offline banner stuck after DevTools network toggle

The online event could fire between page load and useEffect registering
its listener, leaving isOffline stuck at true despite navigator.onLine
being true. A zero-delay setTimeout after listener registration re-syncs
from navigator.onLine, covering that race.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ginnoir
2026-05-06 16:20:49 -05:00
co-authored by Claude Sonnet 4.6
parent afff22e994
commit ec20f1bc87
+6 -4
View File
@@ -4,10 +4,7 @@ import { useEffect, useState } from "react";
export function PwaRegister() {
const [showUpdate, setShowUpdate] = useState(false);
// Lazy init reads navigator.onLine on the client; SSR always returns false.
const [isOffline, setIsOffline] = useState(
() => typeof navigator !== "undefined" && !navigator.onLine
);
const [isOffline, setIsOffline] = useState(false);
const [mutationFailed, setMutationFailed] = useState(false);
useEffect(() => {
@@ -15,6 +12,10 @@ export function PwaRegister() {
const handleOnline = () => setIsOffline(false);
window.addEventListener("offline", handleOffline);
window.addEventListener("online", handleOnline);
// Re-sync after listeners are registered in case the online/offline event
// fired between page load and this effect running (e.g. DevTools toggle).
const syncId = setTimeout(() => setIsOffline(!navigator.onLine), 0);
if (!("serviceWorker" in navigator)) {
return () => {
@@ -48,6 +49,7 @@ export function PwaRegister() {
navigator.serviceWorker.addEventListener("message", handleMessage);
return () => {
clearTimeout(syncId);
window.removeEventListener("offline", handleOffline);
window.removeEventListener("online", handleOnline);
navigator.serviceWorker.removeEventListener(