diff --git a/.changeset/fix-dev-browser-sw-static-route.md b/.changeset/fix-dev-browser-sw-static-route.md new file mode 100644 index 000000000..31b5b77aa --- /dev/null +++ b/.changeset/fix-dev-browser-sw-static-route.md @@ -0,0 +1,5 @@ +--- +"@spencer-kit/coder-studio": patch +--- + +Fix server startup failure when bundled web assets include `dev-browser-sw.js` by excluding the service worker from static file glob registration. diff --git a/packages/server/src/app-routing.test.ts b/packages/server/src/app-routing.test.ts index 65c533ccd..699c64419 100644 --- a/packages/server/src/app-routing.test.ts +++ b/packages/server/src/app-routing.test.ts @@ -294,6 +294,26 @@ describe("app routing", () => { expect(response.body).toContain("coder-studio-dev-browser-session"); }); + it("does not double-register dev-browser-sw.js when it exists in the web root", async () => { + writeFileSync(join(webRoot, "dev-browser-sw.js"), 'const MARKER = "bundled-dev-browser-sw";\n'); + + const instance = await createApp(); + + const getResponse = await instance.inject({ + method: "GET", + url: "/dev-browser-sw.js", + }); + expect(getResponse.statusCode).toBe(200); + expect(getResponse.headers["cache-control"]).toBe("no-cache, no-store, must-revalidate"); + expect(getResponse.body).toContain("bundled-dev-browser-sw"); + + const headResponse = await instance.inject({ + method: "HEAD", + url: "/dev-browser-sw.js", + }); + expect(headResponse.statusCode).toBe(200); + }); + it("serves the dev browser service worker without a configured web root", async () => { const instance = await createApp(false, {}, { webRoot: null }); diff --git a/packages/server/src/app.ts b/packages/server/src/app.ts index c633083ff..8fc0c66df 100644 --- a/packages/server/src/app.ts +++ b/packages/server/src/app.ts @@ -213,7 +213,7 @@ export async function buildFastifyApp(deps: AppDeps): Promise { root: deps.webRoot, prefix: "/", wildcard: false, - globIgnore: ["index.html", "assets/**"], + globIgnore: ["index.html", "assets/**", "dev-browser-sw.js"], maxAge: "1y", immutable: true, });