From fbfba96b9105eebf691c51b15a574bf79e138246 Mon Sep 17 00:00:00 2001 From: Ottomated Date: Tue, 11 Aug 2026 20:22:25 -0700 Subject: [PATCH 1/7] feat: allow adapters to override getRequest and setResponse --- packages/kit/src/exports/public.d.ts | 13 +++++++++++++ packages/kit/src/exports/vite/dev/index.js | 6 +++--- packages/kit/src/exports/vite/preview/index.js | 4 ++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 8f5cf5f0f4a3..eecdde2b0856 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -17,6 +17,7 @@ import { Plugin } from 'vite'; import { RouteId as AppRouteId, LayoutParams as AppLayoutParams } from '$app/types'; import { ParamMatcher } from '@sveltejs/kit/params'; import { StandardSchemaV1 } from '@standard-schema/spec'; +import { getRequest, setResponse } from '@sveltejs/kit/node'; export { PrerenderOption } from '../types/private.js'; @@ -52,6 +53,18 @@ export interface Adapter { */ instrumentation?: () => boolean; }; + /** + * This function overrides the default behavior to convert an `http.IncomingMessage` to a `Request` object. + * To call the original setRequest function, import it from `@sveltejs/kit/node`. + * @since 3.0.0 + */ + getRequest?: typeof getRequest; + /** + * This function overrides the default behavior to write a `Response` object to an `http.ServerResponse`. + * To call the original setResponse function, import it from `@sveltejs/kit/node`. + * @since 3.0.0 + */ + setResponse?: typeof setResponse; /** * Creates an `Emulator`, which allows the adapter to influence the environment * during dev, build and prerendering. diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index 38b295be9e99..8acf6b6f944d 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -591,7 +591,7 @@ export async function dev( read: (file) => createReadableStream(from_fs(file)) }); - const request = getRequest({ + const request = (svelte_config.kit.adapter.getRequest ?? getRequest)({ base, request: req, response: res @@ -644,11 +644,11 @@ export async function dev( // @ts-expect-error serve_static_middleware.handle(req, res, () => { log_response(rendered.status, request); - setResponse(res, rendered); + (svelte_config.kit.adapter.setResponse ?? setResponse)(res, rendered); }); } else { log_response(rendered.status, request); - setResponse(res, rendered); + (svelte_config.kit.adapter.setResponse ?? setResponse)(res, rendered); } } catch (e) { const error = coalesce_to_error(e); diff --git a/packages/kit/src/exports/vite/preview/index.js b/packages/kit/src/exports/vite/preview/index.js index c16b7ef2e8cf..6def40b30f8e 100644 --- a/packages/kit/src/exports/vite/preview/index.js +++ b/packages/kit/src/exports/vite/preview/index.js @@ -204,13 +204,13 @@ export async function preview(vite, vite_config, svelte_config) { vite.middlewares.use(async (req, res) => { const host = req.headers[':authority'] || req.headers.host; - const request = getRequest({ + const request = (svelte_config.kit.adapter.getRequest ?? getRequest)({ base: `${protocol}://${host}`, request: req, response: res }); - setResponse( + (svelte_config.kit.adapter.setResponse ?? setResponse)( res, await server.respond(request, { getClientAddress: () => { From d8e7fca6c7812f6a77df67b4cc325579de36149b Mon Sep 17 00:00:00 2001 From: Ottomated Date: Tue, 11 Aug 2026 20:22:47 -0700 Subject: [PATCH 2/7] changeset --- .changeset/rare-schools-itch.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/rare-schools-itch.md diff --git a/.changeset/rare-schools-itch.md b/.changeset/rare-schools-itch.md new file mode 100644 index 000000000000..3e4cd3ad8926 --- /dev/null +++ b/.changeset/rare-schools-itch.md @@ -0,0 +1,6 @@ +--- +"@sveltejs/kit": minor +--- + +feat: allow adapters to override getRequest and setResponse + \ No newline at end of file From d1276b32f9763c1c0d56246ba398b81b20b70dae Mon Sep 17 00:00:00 2001 From: Ottomated Date: Tue, 11 Aug 2026 20:25:27 -0700 Subject: [PATCH 3/7] generate types --- packages/kit/types/index.d.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index ae5e59c1868d..091b0cf10076 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -4,6 +4,7 @@ declare module '@sveltejs/kit' { import type { Plugin } from 'vite'; import type { RouteId as AppRouteId, LayoutParams as AppLayoutParams } from '$app/types'; + import type { getRequest, setResponse } from '@sveltejs/kit/node'; import type { StandardSchemaV1 } from '@standard-schema/spec'; import type { Config } from '@sveltejs/kit/vite'; // @ts-ignore this is an optional peer dependency so could be missing. Written like this so dts-buddy preserves the ts-ignore @@ -38,6 +39,18 @@ declare module '@sveltejs/kit' { */ instrumentation?: () => boolean; }; + /** + * This function overrides the default behavior to convert an `http.IncomingMessage` to a `Request` object. + * To call the original setRequest function, import it from `@sveltejs/kit/node`. + * @since 3.0.0 + */ + getRequest?: typeof getRequest; + /** + * This function overrides the default behavior to write a `Response` object to an `http.ServerResponse`. + * To call the original setResponse function, import it from `@sveltejs/kit/node`. + * @since 3.0.0 + */ + setResponse?: typeof setResponse; /** * Creates an `Emulator`, which allows the adapter to influence the environment * during dev, build and prerendering. From cda234a34429bd09f478c715d5d6521711fe76e7 Mon Sep 17 00:00:00 2001 From: Ottomated Date: Tue, 11 Aug 2026 20:39:26 -0700 Subject: [PATCH 4/7] optional chaining --- packages/kit/src/exports/vite/dev/index.js | 6 +++--- packages/kit/src/exports/vite/preview/index.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index 8acf6b6f944d..480c6a446edc 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -591,7 +591,7 @@ export async function dev( read: (file) => createReadableStream(from_fs(file)) }); - const request = (svelte_config.kit.adapter.getRequest ?? getRequest)({ + const request = (svelte_config.kit.adapter?.getRequest ?? getRequest)({ base, request: req, response: res @@ -644,11 +644,11 @@ export async function dev( // @ts-expect-error serve_static_middleware.handle(req, res, () => { log_response(rendered.status, request); - (svelte_config.kit.adapter.setResponse ?? setResponse)(res, rendered); + (svelte_config.kit.adapter?.setResponse ?? setResponse)(res, rendered); }); } else { log_response(rendered.status, request); - (svelte_config.kit.adapter.setResponse ?? setResponse)(res, rendered); + (svelte_config.kit.adapter?.setResponse ?? setResponse)(res, rendered); } } catch (e) { const error = coalesce_to_error(e); diff --git a/packages/kit/src/exports/vite/preview/index.js b/packages/kit/src/exports/vite/preview/index.js index 6def40b30f8e..15b61c2390fe 100644 --- a/packages/kit/src/exports/vite/preview/index.js +++ b/packages/kit/src/exports/vite/preview/index.js @@ -204,13 +204,13 @@ export async function preview(vite, vite_config, svelte_config) { vite.middlewares.use(async (req, res) => { const host = req.headers[':authority'] || req.headers.host; - const request = (svelte_config.kit.adapter.getRequest ?? getRequest)({ + const request = (svelte_config.kit.adapter?.getRequest ?? getRequest)({ base: `${protocol}://${host}`, request: req, response: res }); - (svelte_config.kit.adapter.setResponse ?? setResponse)( + (svelte_config.kit.adapter?.setResponse ?? setResponse)( res, await server.respond(request, { getClientAddress: () => { From 8ca42576b7f1f992eebeab0a525513fea386d247 Mon Sep 17 00:00:00 2001 From: Ottomated Date: Tue, 11 Aug 2026 21:59:17 -0700 Subject: [PATCH 5/7] docs --- .../docs/25-build-and-deploy/99-writing-adapters.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/documentation/docs/25-build-and-deploy/99-writing-adapters.md b/documentation/docs/25-build-and-deploy/99-writing-adapters.md index a4002696a018..154c83adf38f 100644 --- a/documentation/docs/25-build-and-deploy/99-writing-adapters.md +++ b/documentation/docs/25-build-and-deploy/99-writing-adapters.md @@ -13,6 +13,8 @@ type AdapterSpecificOptions = any; // @filename: index.js // ---cut--- +import { getRequest, setResponse } from '@sveltejs/kit/node'; + /** @param {AdapterSpecificOptions} options */ export default function (options) { /** @type {import('@sveltejs/kit').Adapter} */ @@ -40,6 +42,15 @@ export default function (options) { // Return `false if it can't, or throw a descriptive error. } }, + getRequest(options) { + const request = getRequest(options); + // modify the Request object here if needed + return request; + }, + setResponse(res, response) { + // handle WebSockets here, for example + setResponse(res, response); + }, vite: { plugins: { // add plugins here to integrate with Vite @@ -53,7 +64,7 @@ export default function (options) { } ``` -Of these, `name` and `adapt` are required. `emulate`, `vite`, and `supports` are optional. +Of these, `name` and `adapt` are required. `emulate`, `vite`, `getRequest`, `setResponse`, and `supports` are optional. Within the `adapt` method, there are a number of things that an adapter should do: From 353413923abccac44f3d17c4c4e49ec361f77fea Mon Sep 17 00:00:00 2001 From: Ottomated Date: Thu, 13 Aug 2026 14:29:36 -0700 Subject: [PATCH 6/7] config changes --- packages/kit/src/exports/vite/dev/index.js | 6 +++--- packages/kit/src/exports/vite/preview/index.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index 480c6a446edc..131d0ff71057 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -591,7 +591,7 @@ export async function dev( read: (file) => createReadableStream(from_fs(file)) }); - const request = (svelte_config.kit.adapter?.getRequest ?? getRequest)({ + const request = (svelte_config.adapter?.getRequest ?? getRequest)({ base, request: req, response: res @@ -644,11 +644,11 @@ export async function dev( // @ts-expect-error serve_static_middleware.handle(req, res, () => { log_response(rendered.status, request); - (svelte_config.kit.adapter?.setResponse ?? setResponse)(res, rendered); + (svelte_config.adapter?.setResponse ?? setResponse)(res, rendered); }); } else { log_response(rendered.status, request); - (svelte_config.kit.adapter?.setResponse ?? setResponse)(res, rendered); + (svelte_config.adapter?.setResponse ?? setResponse)(res, rendered); } } catch (e) { const error = coalesce_to_error(e); diff --git a/packages/kit/src/exports/vite/preview/index.js b/packages/kit/src/exports/vite/preview/index.js index 15b61c2390fe..5f3a1705f0f5 100644 --- a/packages/kit/src/exports/vite/preview/index.js +++ b/packages/kit/src/exports/vite/preview/index.js @@ -204,13 +204,13 @@ export async function preview(vite, vite_config, svelte_config) { vite.middlewares.use(async (req, res) => { const host = req.headers[':authority'] || req.headers.host; - const request = (svelte_config.kit.adapter?.getRequest ?? getRequest)({ + const request = (svelte_config.adapter?.getRequest ?? getRequest)({ base: `${protocol}://${host}`, request: req, response: res }); - (svelte_config.kit.adapter?.setResponse ?? setResponse)( + (svelte_config.adapter?.setResponse ?? setResponse)( res, await server.respond(request, { getClientAddress: () => { From f24c7fced27e08176e5b6499d2a4909ea90e3f33 Mon Sep 17 00:00:00 2001 From: Ottomated Date: Thu, 13 Aug 2026 14:36:42 -0700 Subject: [PATCH 7/7] regen types --- packages/kit/types/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 091b0cf10076..a1c01f07ef32 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -4,8 +4,8 @@ declare module '@sveltejs/kit' { import type { Plugin } from 'vite'; import type { RouteId as AppRouteId, LayoutParams as AppLayoutParams } from '$app/types'; - import type { getRequest, setResponse } from '@sveltejs/kit/node'; import type { StandardSchemaV1 } from '@standard-schema/spec'; + import type { getRequest, setResponse } from '@sveltejs/kit/node'; import type { Config } from '@sveltejs/kit/vite'; // @ts-ignore this is an optional peer dependency so could be missing. Written like this so dts-buddy preserves the ts-ignore type Span = import('@opentelemetry/api').Span;