45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
"use client";
|
|
|
|
/**
|
|
* ServiceWorkerRegistrar — registers the app's service worker for everyone on
|
|
* load (not just when a user opts into push). The same `/sw.js` now also
|
|
* powers the Save-offline feature (caching page HTML + assets), so it must be
|
|
* active regardless of push. The `?bff=` query matches the push registration
|
|
* exactly (see lib/push.ts) so there's a single registration / scope, and push
|
|
* subscription management keeps working.
|
|
*/
|
|
|
|
import { useEffect } from "react";
|
|
import { precacheOfflineLibrary } from "@/lib/offline";
|
|
|
|
const BFF_BASE = process.env.NEXT_PUBLIC_BFF_URL || "http://localhost:8080";
|
|
|
|
export function ServiceWorkerRegistrar() {
|
|
useEffect(() => {
|
|
if (typeof navigator === "undefined" || !("serviceWorker" in navigator)) {
|
|
return;
|
|
}
|
|
const register = () => {
|
|
navigator.serviceWorker
|
|
.register(`/sw.js?bff=${encodeURIComponent(BFF_BASE)}`)
|
|
.then(() => {
|
|
// Precache the offline library so it works as the SW navigation
|
|
// fallback even if the user never opens it online.
|
|
void precacheOfflineLibrary();
|
|
})
|
|
.catch(() => {
|
|
/* registration is best-effort; the app works online without it */
|
|
});
|
|
};
|
|
// Defer past first paint so it never competes with hydration.
|
|
if (document.readyState === "complete") {
|
|
register();
|
|
return;
|
|
}
|
|
window.addEventListener("load", register, { once: true });
|
|
return () => window.removeEventListener("load", register);
|
|
}, []);
|
|
|
|
return null;
|
|
}
|