diff --git a/.changeset/head-page-fallthrough.md b/.changeset/head-page-fallthrough.md new file mode 100644 index 000000000..ac2c8493b --- /dev/null +++ b/.changeset/head-page-fallthrough.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": patch +--- + +Serve the page for a `HEAD` request when a route file exports both a page and a `GET` that returns nothing, such as a `[...404].tsx`. The server threw "did not return a response" and answered 500 instead of rendering the page as it does for `GET`. diff --git a/apps/tests/src/e2e/api-call.test.ts b/apps/tests/src/e2e/api-call.test.ts index e216f8956..4665d75d5 100644 --- a/apps/tests/src/e2e/api-call.test.ts +++ b/apps/tests/src/e2e/api-call.test.ts @@ -22,6 +22,16 @@ test.describe("api calls", () => { expect(redirectResp.headers.get("x-shared-header")).toBe("event"); }); + test("should serve the page for HEAD when the GET handler returns nothing", async () => { + // `[...404].tsx` exports a page and a `GET` that only answers JSON requests. + const get = await fetch("http://localhost:3000/no-such-page"); + const head = await fetch("http://localhost:3000/no-such-page", { method: "HEAD" }); + + expect(get.status).toBe(404); + expect(head.status).toBe(get.status); + expect(head.headers.get("content-type")).toBe(get.headers.get("content-type")); + }); + test("should preserve multiple Set-Cookie headers on redirect (RFC 6265)", async () => { const response = await fetch("http://localhost:3000/api/multi-set-cookie-redirect", { redirect: "manual", diff --git a/packages/start/src/server/handler.ts b/packages/start/src/server/handler.ts index a705537d6..999badc17 100644 --- a/packages/start/src/server/handler.ts +++ b/packages/start/src/server/handler.ts @@ -47,7 +47,9 @@ export function createBaseHandler( if (res !== undefined) { return res; } - if (event.request.method !== "GET") { + // A HEAD request runs the `GET` handler when there is no `HEAD` one, + // so it falls through to the page the same way a `GET` does. + if (event.request.method !== "GET" && event.request.method !== "HEAD") { throw new Error( `API handler for ${event.request.method} "${event.request.url}" did not return a response.`, );