From 63f8d467b4def1af0de653835f8243528e53b853 Mon Sep 17 00:00:00 2001 From: Tee Ming Chew Date: Sat, 25 Jul 2026 06:37:15 +0800 Subject: [PATCH 01/10] check page option instead of prerenderer options --- packages/kit/src/runtime/server/page/index.js | 4 ++-- packages/kit/src/runtime/server/page/load_data.js | 2 +- packages/kit/src/runtime/server/page/render.js | 14 +++++++------- packages/kit/src/runtime/server/respond.js | 2 +- packages/kit/src/types/internal.d.ts | 3 ++- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/kit/src/runtime/server/page/index.js b/packages/kit/src/runtime/server/page/index.js index bd90f2a48423..3b4067314b8e 100644 --- a/packages/kit/src/runtime/server/page/index.js +++ b/packages/kit/src/runtime/server/page/index.js @@ -122,7 +122,7 @@ export async function render_page( // renders an empty 'shell' page if SSR is turned off and if there is // no server data to prerender. As a result, the load functions and rendering // only occur client-side. - if (ssr === false && !(state.prerendering && should_prerender_data)) { + if (ssr === false && !(should_prerender && should_prerender_data)) { // if the user makes a request through a non-enhanced form, the returned value is lost // because there is no SSR or client-side handling of the response if (DEV && action_result && !event.request.headers.has('x-sveltekit-action')) { @@ -173,7 +173,7 @@ export async function render_page( const data_serializer = server_data_serializer(event, event_state, options); const data_serializer_json = - state.prerendering && should_prerender_data + should_prerender && should_prerender_data ? server_data_serializer_json(event, event_state, options) : null; diff --git a/packages/kit/src/runtime/server/page/load_data.js b/packages/kit/src/runtime/server/page/load_data.js index a7043ff8028b..b139f25f1d3b 100644 --- a/packages/kit/src/runtime/server/page/load_data.js +++ b/packages/kit/src/runtime/server/page/load_data.js @@ -67,7 +67,7 @@ export async function load_server_data({ event, event_state, state, node, parent } ); - if (state.prerendering) { + if (state.prerender_default) { disable_search(url); } diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index 676afaf8f56d..9c132c0623c0 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -58,7 +58,7 @@ export async function render_response({ data_serializer, error_components }) { - if (state.prerendering) { + if (state.prerender_default) { if (options.csp.mode === 'nonce') { throw new Error('Cannot use prerendering if config.csp.mode === "nonce"'); } @@ -106,7 +106,7 @@ export async function render_response({ let base_expression = s(paths.base); const csp = new Csp(options.csp, { - prerender: !!state.prerendering + prerender: !!state.prerender_default }); // if appropriate, use relative paths for greater portability @@ -310,7 +310,7 @@ export async function render_response({ * @param {string[]} attributes */ const add_preload = (path, attributes) => { - if (options.link_header_preload && !state.prerendering) { + if (options.link_header_preload && !state.prerender_default) { link_headers.add(`<${encodeURI(path)}>; ${attributes.join('; ')}; nopush`); } else { head.add_link_tag(path, attributes); @@ -351,7 +351,7 @@ export async function render_response({ if (page_config.ssr && page_config.csr) { body += `\n\t\t\t${fetched .map((item) => - serialize_data(item, resolve_opts.filterSerializedResponseHeaders, !!state.prerendering) + serialize_data(item, resolve_opts.filterSerializedResponseHeaders, !!state.prerender_default) ) .join('\n\t\t\t')}`; } @@ -363,7 +363,7 @@ export async function render_response({ // import the env.js module so that it evaluates before any user code can evaluate. // TODO revert to using top-level await once https://bugs.webkit.org/show_bug.cgi?id=242740 is fixed // https://github.com/sveltejs/kit/pull/11601 - const load_env_eagerly = client.uses_env_dynamic_public && !!state.prerendering; + const load_env_eagerly = client.uses_env_dynamic_public && !!state.prerender_default; if (load_env_eagerly) { modulepreloads.add(`${paths.app_dir}/env.js`); @@ -568,14 +568,14 @@ export async function render_response({ 'content-type': 'text/html' }); - if (state.prerendering) { + if (state.prerendering || state.prerender_default) { // TODO read headers set with setHeaders and convert into http-equiv where possible const csp_headers = csp.csp_provider.get_meta(); if (csp_headers) { head.add_http_equiv(csp_headers); } - if (state.prerendering.cache) { + if (state.prerendering?.cache) { head.add_http_equiv( `` ); diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index be9b86052bec..788d855b1c7f 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -435,7 +435,7 @@ export async function internal_respond(request, options, manifest, state) { prerender = node.prerender ?? prerender; } else if (page_nodes) { config = page_nodes.get_config() ?? config; - prerender = page_nodes.prerender(); + prerender = state.prerender_default = page_nodes.prerender(); } if (state.emulator?.platform) { diff --git a/packages/kit/src/types/internal.d.ts b/packages/kit/src/types/internal.d.ts index 1eeb6f6dee94..e29764189a06 100644 --- a/packages/kit/src/types/internal.d.ts +++ b/packages/kit/src/types/internal.d.ts @@ -185,7 +185,7 @@ export class InternalServer extends Server { /** @internal used during development to check feature availability depending on the current route */ before_handle?: ( event: RequestEvent, - config: any, + config: Record, prerender: PrerenderOption, handle: () => Promise ) => Promise; @@ -233,6 +233,7 @@ export interface PrerenderDependency { body: null | string | Uint8Array; } +/** Internal context for the prerendering process */ export interface PrerenderOptions { cache?: string; // including this here is a bit of a hack, but it makes it easy to add fallback?: boolean; From aedc4e08b1b2e8e285e082972e7749dd1d5f78ae Mon Sep 17 00:00:00 2001 From: Tee Ming Chew Date: Sat, 25 Jul 2026 06:41:32 +0800 Subject: [PATCH 02/10] format --- packages/kit/src/runtime/server/page/render.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index 9c132c0623c0..1d625d017c8d 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -351,7 +351,11 @@ export async function render_response({ if (page_config.ssr && page_config.csr) { body += `\n\t\t\t${fetched .map((item) => - serialize_data(item, resolve_opts.filterSerializedResponseHeaders, !!state.prerender_default) + serialize_data( + item, + resolve_opts.filterSerializedResponseHeaders, + !!state.prerender_default + ) ) .join('\n\t\t\t')}`; } From 782a2a5e4acaf22d21ab2df98345edf32213cc65 Mon Sep 17 00:00:00 2001 From: Tee Ming Chew Date: Sat, 25 Jul 2026 06:43:21 +0800 Subject: [PATCH 03/10] changeset --- .changeset/silent-bushes-grow.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/silent-bushes-grow.md diff --git a/.changeset/silent-bushes-grow.md b/.changeset/silent-bushes-grow.md new file mode 100644 index 000000000000..d2befebda630 --- /dev/null +++ b/.changeset/silent-bushes-grow.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: surface prerender errors during development From ae3759a35f79d446602ec05d107ac381b2f40a33 Mon Sep 17 00:00:00 2001 From: Tee Ming Date: Sat, 25 Jul 2026 06:53:10 +0800 Subject: [PATCH 04/10] Apply suggestion from @teemingc --- packages/kit/src/runtime/server/page/load_data.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kit/src/runtime/server/page/load_data.js b/packages/kit/src/runtime/server/page/load_data.js index b139f25f1d3b..08993c606297 100644 --- a/packages/kit/src/runtime/server/page/load_data.js +++ b/packages/kit/src/runtime/server/page/load_data.js @@ -67,7 +67,7 @@ export async function load_server_data({ event, event_state, state, node, parent } ); - if (state.prerender_default) { + if (state.prerendering || state.prerender_default === true) { disable_search(url); } From 7d25bffc250ba5d32f3752accf288d00ba9ea602 Mon Sep 17 00:00:00 2001 From: Tee Ming Date: Sat, 25 Jul 2026 06:55:23 +0800 Subject: [PATCH 05/10] Apply suggestions from code review Co-authored-by: Tee Ming --- packages/kit/src/runtime/server/page/render.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index 1d625d017c8d..0bb5dfaec955 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -58,7 +58,7 @@ export async function render_response({ data_serializer, error_components }) { - if (state.prerender_default) { + if (state.prerendering || state.prerender_default === true) { if (options.csp.mode === 'nonce') { throw new Error('Cannot use prerendering if config.csp.mode === "nonce"'); } @@ -106,7 +106,7 @@ export async function render_response({ let base_expression = s(paths.base); const csp = new Csp(options.csp, { - prerender: !!state.prerender_default + prerender: state.prerendering || state.prerender_default === true }); // if appropriate, use relative paths for greater portability @@ -310,7 +310,7 @@ export async function render_response({ * @param {string[]} attributes */ const add_preload = (path, attributes) => { - if (options.link_header_preload && !state.prerender_default) { + if (options.link_header_preload && !(state.prerendering || state.prerender_default === true) { link_headers.add(`<${encodeURI(path)}>; ${attributes.join('; ')}; nopush`); } else { head.add_link_tag(path, attributes); From 009fa715a05f55f96df9bcfe5fc589ea42421ae6 Mon Sep 17 00:00:00 2001 From: Tee Ming Date: Sat, 25 Jul 2026 06:56:14 +0800 Subject: [PATCH 06/10] Apply suggestion from @teemingc --- packages/kit/src/runtime/server/page/render.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index 0bb5dfaec955..ffb24471b552 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -367,7 +367,7 @@ export async function render_response({ // import the env.js module so that it evaluates before any user code can evaluate. // TODO revert to using top-level await once https://bugs.webkit.org/show_bug.cgi?id=242740 is fixed // https://github.com/sveltejs/kit/pull/11601 - const load_env_eagerly = client.uses_env_dynamic_public && !!state.prerender_default; + const load_env_eagerly = client.uses_env_dynamic_public && (state.prerendering || state.prerender_default === true); if (load_env_eagerly) { modulepreloads.add(`${paths.app_dir}/env.js`); From 5428e028745a4be2fce1099766bb6a546e9e77ef Mon Sep 17 00:00:00 2001 From: Tee Ming Date: Sat, 25 Jul 2026 06:56:42 +0800 Subject: [PATCH 07/10] Apply suggestions from code review Co-authored-by: Tee Ming --- packages/kit/src/types/internal.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kit/src/types/internal.d.ts b/packages/kit/src/types/internal.d.ts index e29764189a06..7093c8db58f4 100644 --- a/packages/kit/src/types/internal.d.ts +++ b/packages/kit/src/types/internal.d.ts @@ -185,7 +185,7 @@ export class InternalServer extends Server { /** @internal used during development to check feature availability depending on the current route */ before_handle?: ( event: RequestEvent, - config: Record, + config: any, prerender: PrerenderOption, handle: () => Promise ) => Promise; From f5517184b111b5dc44ba1ea0e00e16e1bb5168da Mon Sep 17 00:00:00 2001 From: Tee Ming Date: Sat, 25 Jul 2026 06:57:45 +0800 Subject: [PATCH 08/10] Apply suggestions from code review Co-authored-by: Tee Ming --- packages/kit/src/runtime/server/page/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/kit/src/runtime/server/page/index.js b/packages/kit/src/runtime/server/page/index.js index 3b4067314b8e..34f8436657b8 100644 --- a/packages/kit/src/runtime/server/page/index.js +++ b/packages/kit/src/runtime/server/page/index.js @@ -122,7 +122,7 @@ export async function render_page( // renders an empty 'shell' page if SSR is turned off and if there is // no server data to prerender. As a result, the load functions and rendering // only occur client-side. - if (ssr === false && !(should_prerender && should_prerender_data)) { + if (ssr === false && !((state.prerendering || state. should_prerender === true) && should_prerender_data)) { // if the user makes a request through a non-enhanced form, the returned value is lost // because there is no SSR or client-side handling of the response if (DEV && action_result && !event.request.headers.has('x-sveltekit-action')) { @@ -173,7 +173,7 @@ export async function render_page( const data_serializer = server_data_serializer(event, event_state, options); const data_serializer_json = - should_prerender && should_prerender_data + (state.prerendering || state.should_prerender === true) && should_prerender_data ? server_data_serializer_json(event, event_state, options) : null; From 98d146a3bf2fe534d9147b21abba1aad2c2c468c Mon Sep 17 00:00:00 2001 From: Tee Ming Chew Date: Sat, 25 Jul 2026 07:09:03 +0800 Subject: [PATCH 09/10] fix --- packages/kit/src/runtime/server/page/index.js | 7 +++++-- packages/kit/src/runtime/server/page/render.js | 5 +++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/kit/src/runtime/server/page/index.js b/packages/kit/src/runtime/server/page/index.js index 34f8436657b8..22a577417c23 100644 --- a/packages/kit/src/runtime/server/page/index.js +++ b/packages/kit/src/runtime/server/page/index.js @@ -122,7 +122,10 @@ export async function render_page( // renders an empty 'shell' page if SSR is turned off and if there is // no server data to prerender. As a result, the load functions and rendering // only occur client-side. - if (ssr === false && !((state.prerendering || state. should_prerender === true) && should_prerender_data)) { + if ( + ssr === false && + !((state.prerendering || state.prerender_default === true) && should_prerender_data) + ) { // if the user makes a request through a non-enhanced form, the returned value is lost // because there is no SSR or client-side handling of the response if (DEV && action_result && !event.request.headers.has('x-sveltekit-action')) { @@ -173,7 +176,7 @@ export async function render_page( const data_serializer = server_data_serializer(event, event_state, options); const data_serializer_json = - (state.prerendering || state.should_prerender === true) && should_prerender_data + (state.prerendering || state.prerender_default === true) && should_prerender_data ? server_data_serializer_json(event, event_state, options) : null; diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index ffb24471b552..edf048cd3188 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -310,7 +310,7 @@ export async function render_response({ * @param {string[]} attributes */ const add_preload = (path, attributes) => { - if (options.link_header_preload && !(state.prerendering || state.prerender_default === true) { + if (options.link_header_preload && !(state.prerendering || state.prerender_default === true)) { link_headers.add(`<${encodeURI(path)}>; ${attributes.join('; ')}; nopush`); } else { head.add_link_tag(path, attributes); @@ -367,7 +367,8 @@ export async function render_response({ // import the env.js module so that it evaluates before any user code can evaluate. // TODO revert to using top-level await once https://bugs.webkit.org/show_bug.cgi?id=242740 is fixed // https://github.com/sveltejs/kit/pull/11601 - const load_env_eagerly = client.uses_env_dynamic_public && (state.prerendering || state.prerender_default === true); + const load_env_eagerly = + client.uses_env_dynamic_public && (state.prerendering || state.prerender_default === true); if (load_env_eagerly) { modulepreloads.add(`${paths.app_dir}/env.js`); From 8ef31c60382b3ccd9eca70f5a0599938b642cf0c Mon Sep 17 00:00:00 2001 From: Tee Ming Chew Date: Sat, 25 Jul 2026 07:16:00 +0800 Subject: [PATCH 10/10] fixes --- packages/kit/src/runtime/server/page/render.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index edf048cd3188..a543f91de230 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -106,7 +106,7 @@ export async function render_response({ let base_expression = s(paths.base); const csp = new Csp(options.csp, { - prerender: state.prerendering || state.prerender_default === true + prerender: !!(state.prerendering || state.prerender_default === true) }); // if appropriate, use relative paths for greater portability @@ -354,7 +354,7 @@ export async function render_response({ serialize_data( item, resolve_opts.filterSerializedResponseHeaders, - !!state.prerender_default + !!(state.prerendering || state.prerender_default === true) ) ) .join('\n\t\t\t')}`; @@ -573,7 +573,7 @@ export async function render_response({ 'content-type': 'text/html' }); - if (state.prerendering || state.prerender_default) { + if (state.prerendering || state.prerender_default === true) { // TODO read headers set with setHeaders and convert into http-equiv where possible const csp_headers = csp.csp_provider.get_meta(); if (csp_headers) {