Last active
January 5, 2023 16:27
-
-
Save baptistemanson/d38c260b68acd64cbbb2cb764b00721d to your computer and use it in GitHub Desktop.
example hack for service worker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
useEffect(() => { | |
if (!navigator.serviceWorker) | |
throw new Error("We only support browsers with service workers enabled"); | |
// The trickery below appears to be necessary to register a compiled ServiceWorker with nextjs | |
// Webpack only compiles workers imported via the pattern `new Worker(new URL("script_to_be_compiled"))` | |
// So we need to use that exact expression and have it register a service worker instead | |
const RealWorker = window.Worker; | |
( | |
window as any | |
).Worker = class FakeWorkerRegisteringServiceWorkerToTrickNextjs { | |
constructor(url: URL) { | |
// We need to change the scope to / since the script compiled by nextjs will be placed in the _next/static/chunks directory | |
// By default the service worker takes the scope of its source files and only handles requests from pages under that scope | |
// To change the scope we must allow it by attaching the Service-Worker-Allowed header (see next.config.js) | |
navigator.serviceWorker.register(url, { scope: "/" }).then( | |
async (_registration) => { | |
await navigator.serviceWorker.ready; | |
debug("sync-main")("service worker is ready"); | |
setIsSWReady(true); | |
}, | |
(err) => console.error(err), | |
); | |
} | |
}; | |
new Worker(new URL("../service-worker/index.ts", import.meta.url)); | |
window.Worker = RealWorker; | |
// The ServiceWorker that was just registered still needs to "claim" this page | |
// and the `navigator.serviceWorker.controller` will not be available until this happes | |
// Waiting on the navigator.serviceWorker.register(...) promise or navigator.serviceWorker.ready | |
// is not enough, since a service worker may be activated without claiming pages at all | |
navigator.serviceWorker.addEventListener("controllerchange", (e) => { | |
debug("sync-main")("change of controller"); | |
setSWId(nanoid()); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment