From 49e42de2404617ed0d8ae6328affca79c7b554b0 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 5940db4e1d1b..1e561e098935 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 566693e41959..7e2d9a3728de 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -592,7 +592,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 @@ -645,11 +645,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 9b7d77d4cae9f8773ca2461b348f967f0e0003c8 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 b95b69fe0945ff8c9fa05821ee04058cccbfcbbd 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 b42fd7122fc4..f37238b8495c 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 74dedc70e10e11bd4ecb95ebb0d9cd658aa0254f 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 7e2d9a3728de..d0119e0747ca 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -592,7 +592,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 @@ -645,11 +645,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 3026d4bac893e0672cf15ee5f47ef18024a6b1ae 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 3aaaf86438a4ce60593078e79750be732faaf5cf 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 d0119e0747ca..99a890c28a9d 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -592,7 +592,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 @@ -645,11 +645,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 0eb057fb61d2471f59799b0f39e0a2543a575ca4 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 f37238b8495c..ae2b1cae07a5 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;