diff --git a/.changeset/spicy-rockets-ring.md b/.changeset/spicy-rockets-ring.md new file mode 100644 index 000000000000..5b7808fadc54 --- /dev/null +++ b/.changeset/spicy-rockets-ring.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +feat: server js fallthrough to page if method handler doesn't exist diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index 1cd9d058ad6b..d2945a2906bf 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -378,11 +378,8 @@ export async function respond(request, options, manifest, state) { } if (route) { - /** @type {Response} */ - let response; - if (is_data_request) { - response = await render_data( + return await render_data( event, route, options, @@ -392,16 +389,26 @@ export async function respond(request, options, manifest, state) { trailing_slash ?? 'never' ); } else if (route.endpoint && (!route.page || is_endpoint_request(event))) { - response = await render_endpoint(event, await route.endpoint(), state); + const endpoint = await route.endpoint(); + const response = await render_endpoint(event, endpoint, state); + + // If endpoint doesn't have a handler for these methods, fall back to the page + if ( + response.status === 405 && + route.page && + ['HEAD', 'GET', 'POST'].includes(event.request.method) + ) { + return await render_page(event, route.page, options, manifest, state, resolve_opts); + } else { + return response; + } } else if (route.page) { - response = await render_page(event, route.page, options, manifest, state, resolve_opts); + return await render_page(event, route.page, options, manifest, state, resolve_opts); } else { // a route will always have a page or an endpoint, but TypeScript // doesn't know that throw new Error('This should never happen'); } - - return response; } if (state.error) { diff --git a/packages/kit/test/apps/basics/src/routes/routing/endpoint-fallthrough/+page.svelte b/packages/kit/test/apps/basics/src/routes/routing/endpoint-fallthrough/+page.svelte new file mode 100644 index 000000000000..67b49df13feb --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/routing/endpoint-fallthrough/+page.svelte @@ -0,0 +1 @@ +
Hello from the page!
diff --git a/packages/kit/test/apps/basics/src/routes/routing/endpoint-fallthrough/+server.js b/packages/kit/test/apps/basics/src/routes/routing/endpoint-fallthrough/+server.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/kit/test/apps/basics/test/server.test.js b/packages/kit/test/apps/basics/test/server.test.js index 05424811609b..52c438486a43 100644 --- a/packages/kit/test/apps/basics/test/server.test.js +++ b/packages/kit/test/apps/basics/test/server.test.js @@ -199,6 +199,13 @@ test.describe('Endpoints', () => { expect(response.status()).toBe(200); expect(await response.text()).toBe('ok'); }); + + test('falls back to page if no matching handler found', async ({ request }) => { + const response = await request.get('/routing/endpoint-fallthrough'); + + expect(response.status()).toBe(200); + expect(await response.text()).toContain('Hello from the page!'); + }); }); test.describe('Errors', () => {