diff --git a/apps/tests/src/e2e/http-header.test.ts b/apps/tests/src/e2e/http-header.test.ts new file mode 100644 index 000000000..572a77721 --- /dev/null +++ b/apps/tests/src/e2e/http-header.test.ts @@ -0,0 +1,10 @@ +import { expect, test } from "@playwright/test"; + +test.describe("http header", () => { + // couldn't get this to see the headers but verified in chrome devtools + test.skip("should set http header", async ({ page }) => { + const response = await page.goto("/http-header"); + + expect(response?.headers()["test-header"]).toBe("test-value"); + }); +}); diff --git a/apps/tests/src/routes/http-header.tsx b/apps/tests/src/routes/http-header.tsx new file mode 100644 index 000000000..a12d99293 --- /dev/null +++ b/apps/tests/src/routes/http-header.tsx @@ -0,0 +1,10 @@ +import { HttpHeader } from "@solidjs/start"; + +export default function HttpHeaderRoute() { + return ( +
+

Http Header

+ +
+ ); +} diff --git a/packages/start/src/index.ts b/packages/start/src/index.ts index ccde895b2..be39a77a3 100644 --- a/packages/start/src/index.ts +++ b/packages/start/src/index.ts @@ -10,9 +10,10 @@ export type { HandlerOptions, PageEvent, ResponseStub, - ServerFunctionMeta, + ServerFunctionMeta } from "./server/types.ts"; export { default as clientOnly } from "./shared/clientOnly.ts"; export { GET } from "./shared/GET.ts"; +export { HttpHeader } from "./shared/HttpHeader.tsx"; export { HttpStatusCode } from "./shared/HttpStatusCode.ts"; export { getServerFunctionMeta } from "./shared/serverFunction.ts"; diff --git a/packages/start/src/shared/HttpHeader.tsx b/packages/start/src/shared/HttpHeader.tsx new file mode 100644 index 000000000..30e061a4c --- /dev/null +++ b/packages/start/src/shared/HttpHeader.tsx @@ -0,0 +1,42 @@ +// @refresh skip +import { onCleanup } from "solid-js"; +import { getRequestEvent, isServer } from "solid-js/web"; + +import type { PageEvent } from "../server/types.ts"; +import { appendHeader, setHeader } from "../http/index.ts"; + +export interface HttpHeaderProps { + name: string; + value: string; + append?: boolean; +} + +/** + * + * Read more: https://docs.solidjs.com/solid-start/reference/server/http-header + */ +export const HttpHeader = isServer + ? (props: HttpHeaderProps) => { + const event = getRequestEvent() as PageEvent; + + if (props.append) appendHeader(props.name, props.value); + else setHeader(props.name, props.value); + + onCleanup(() => { + // @ts-expect-error + if (event.nativeEvent.handled || event.complete) return; + const value = event.response.headers.get(props.name); + if (!value) return; + if (!value.includes(", ")) { + if (value === props.value) event.response.headers.delete(props.name); + return; + } + const values = value.split(", "); + const index = values.indexOf(props.value); + index !== -1 && values.splice(index, 1); + if (values.length) event.response.headers.set(props.name, values.join(",")); + else event.response.headers.delete(props.name); + }); + return null; + } + : (_props: HttpHeaderProps) => null;