From 9ea1116de5e4ed7269773a1d50a4ae1bb03dfbdd Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Wed, 9 Apr 2025 14:58:26 +0800 Subject: [PATCH 1/5] fix --- packages/kit/src/runtime/server/page/index.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/kit/src/runtime/server/page/index.js b/packages/kit/src/runtime/server/page/index.js index 01337e4cac1c..bcab3b5e2701 100644 --- a/packages/kit/src/runtime/server/page/index.js +++ b/packages/kit/src/runtime/server/page/index.js @@ -93,10 +93,13 @@ export async function render_page(event, page, options, manifest, state, nodes, /** @type {import('./types.js').Fetched[]} */ const fetched = []; + const ssr = nodes.ssr(); + const csr = nodes.csr(); + // 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 (nodes.ssr() === false && !(state.prerendering && should_prerender_data)) { + if (ssr === false && !(state.prerendering && 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')) { @@ -117,7 +120,7 @@ export async function render_page(event, page, options, manifest, state, nodes, fetched, page_config: { ssr: false, - csr: nodes.csr() + csr }, status, error: null, @@ -171,8 +174,6 @@ export async function render_page(event, page, options, manifest, state, nodes, }); }); - const csr = nodes.csr(); - /** @type {Array | null>>} */ const load_promises = nodes.data.map((node, i) => { if (load_error) throw load_error; @@ -250,7 +251,10 @@ export async function render_page(event, page, options, manifest, state, nodes, manifest, state, resolve_opts, - page_config: { ssr: true, csr: true }, + page_config: { + ssr, + csr + }, status, error, branch: compact(branch.slice(0, j + 1)).concat({ @@ -294,8 +298,6 @@ export async function render_page(event, page, options, manifest, state, nodes, }); } - const ssr = nodes.ssr(); - return await render_response({ event, options, @@ -303,7 +305,7 @@ export async function render_page(event, page, options, manifest, state, nodes, state, resolve_opts, page_config: { - csr: nodes.csr(), + csr, ssr }, status, From 096a7294a8f8816290612333928b04be9a0a60bf Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Wed, 9 Apr 2025 14:59:32 +0800 Subject: [PATCH 2/5] changeset --- .changeset/khaki-queens-provide.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/khaki-queens-provide.md diff --git a/.changeset/khaki-queens-provide.md b/.changeset/khaki-queens-provide.md new file mode 100644 index 000000000000..4faf893883a7 --- /dev/null +++ b/.changeset/khaki-queens-provide.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: ensure that `ssr` and `csr` page options apply to error pages rendered as a result of a load function error From 4236765900cec03bc3bf4f6bc7a999649a799f15 Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Wed, 9 Apr 2025 15:03:27 +0800 Subject: [PATCH 3/5] edit changeset --- .changeset/khaki-queens-provide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/khaki-queens-provide.md b/.changeset/khaki-queens-provide.md index 4faf893883a7..74571d33e5de 100644 --- a/.changeset/khaki-queens-provide.md +++ b/.changeset/khaki-queens-provide.md @@ -2,4 +2,4 @@ '@sveltejs/kit': patch --- -fix: ensure that `ssr` and `csr` page options apply to error pages rendered as a result of a load function error +fix: ensure that `ssr` and `csr` page options apply to error pages rendered as a result of a load function error on the server From 5266a4c602ab8afa39915ddc6c06e229bb0e8656 Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Wed, 9 Apr 2025 15:23:30 +0800 Subject: [PATCH 4/5] add test --- .../errors/load-error-page-options/+error.svelte | 5 +++++ .../routes/errors/load-error-page-options/+layout.js | 2 ++ .../routes/errors/load-error-page-options/+page.js | 3 +++ packages/kit/test/apps/basics/test/server.test.js | 11 +++++++++++ 4 files changed, 21 insertions(+) create mode 100644 packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/+error.svelte create mode 100644 packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/+layout.js create mode 100644 packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/+page.js diff --git a/packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/+error.svelte b/packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/+error.svelte new file mode 100644 index 000000000000..b4ac29aec4b9 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/+error.svelte @@ -0,0 +1,5 @@ + + +

{$page.error.message}

diff --git a/packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/+layout.js b/packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/+layout.js new file mode 100644 index 000000000000..7c8af84c5b54 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/+layout.js @@ -0,0 +1,2 @@ +// disables csr for the error page +export const csr = false; diff --git a/packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/+page.js b/packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/+page.js new file mode 100644 index 000000000000..6fb722159401 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/+page.js @@ -0,0 +1,3 @@ +export function load() { + throw new Error('Crashing now'); +} diff --git a/packages/kit/test/apps/basics/test/server.test.js b/packages/kit/test/apps/basics/test/server.test.js index eb8572489fb0..42b3b9daf845 100644 --- a/packages/kit/test/apps/basics/test/server.test.js +++ b/packages/kit/test/apps/basics/test/server.test.js @@ -462,6 +462,17 @@ test.describe('Errors', () => { }); } }); + + test('error thrown from load on the server respects page options when rendering the error page', async ({ + request + }) => { + const res = await request.get('/errors/load-error-page-options'); + expect(res.status()).toBe(500); + const content = await res.text(); + expect(content).toContain('Crashing now'); + // the hydration script should not be present if the csr page option is respected + expect(content).not.toContain('kit.start(app'); + }); }); test.describe('Load', () => { From 117958ce9fed12f15d33fc1c45cf2e63c27a5767 Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Wed, 9 Apr 2025 16:00:48 +0800 Subject: [PATCH 5/5] use the page options for the nearest error page --- packages/kit/src/runtime/server/page/index.js | 10 +++++++--- .../errors/load-error-page-options/csr/+layout.js | 1 + .../errors/load-error-page-options/{ => csr}/+page.js | 0 packages/kit/test/apps/basics/test/server.test.js | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/csr/+layout.js rename packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/{ => csr}/+page.js (100%) diff --git a/packages/kit/src/runtime/server/page/index.js b/packages/kit/src/runtime/server/page/index.js index bcab3b5e2701..e7b462a74dda 100644 --- a/packages/kit/src/runtime/server/page/index.js +++ b/packages/kit/src/runtime/server/page/index.js @@ -15,6 +15,7 @@ import { render_response } from './render.js'; import { respond_with_error } from './respond_with_error.js'; import { get_data_json } from '../data/index.js'; import { DEV } from 'esm-env'; +import { PageNodes } from '../../../utils/page_nodes.js'; /** * The maximum request depth permitted before assuming we're stuck in an infinite loop @@ -245,6 +246,9 @@ export async function render_page(event, page, options, manifest, state, nodes, let j = i; while (!branch[j]) j -= 1; + const layouts = compact(branch.slice(0, j + 1)); + const nodes = new PageNodes(layouts.map((layout) => layout.node)); + return await render_response({ event, options, @@ -252,12 +256,12 @@ export async function render_page(event, page, options, manifest, state, nodes, state, resolve_opts, page_config: { - ssr, - csr + ssr: nodes.ssr(), + csr: nodes.csr() }, status, error, - branch: compact(branch.slice(0, j + 1)).concat({ + branch: layouts.concat({ node, data: null, server_data: null diff --git a/packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/csr/+layout.js b/packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/csr/+layout.js new file mode 100644 index 000000000000..ce9d762e74cf --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/csr/+layout.js @@ -0,0 +1 @@ +export const csr = true; diff --git a/packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/+page.js b/packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/csr/+page.js similarity index 100% rename from packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/+page.js rename to packages/kit/test/apps/basics/src/routes/errors/load-error-page-options/csr/+page.js diff --git a/packages/kit/test/apps/basics/test/server.test.js b/packages/kit/test/apps/basics/test/server.test.js index 42b3b9daf845..d18a01f11f67 100644 --- a/packages/kit/test/apps/basics/test/server.test.js +++ b/packages/kit/test/apps/basics/test/server.test.js @@ -466,7 +466,7 @@ test.describe('Errors', () => { test('error thrown from load on the server respects page options when rendering the error page', async ({ request }) => { - const res = await request.get('/errors/load-error-page-options'); + const res = await request.get('/errors/load-error-page-options/csr'); expect(res.status()).toBe(500); const content = await res.text(); expect(content).toContain('Crashing now');