From 86e2233fa186ec38a9681ee12275410b709cb918 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Wed, 10 Sep 2025 13:55:42 +0200 Subject: [PATCH 1/3] fix: enable redirects from queries Some later refactorings in the original remote functions PR broke the "redirect from query"-feature. This fixes that, and also removes some TODO-analyse-code which is no longer necesary fixes #14380 --- .changeset/forty-dots-punch.md | 5 +++++ .../client/remote-functions/query.svelte.js | 2 -- .../client/remote-functions/shared.svelte.js | 6 ------ packages/kit/src/runtime/server/remote.js | 8 +++---- .../routes/remote/query-redirect/+page.svelte | 2 ++ .../from-common-layout/+layout.svelte | 13 ++++++++++++ .../from-common-layout/+page.svelte | 1 + .../redirected/+page.svelte | 1 + .../query-redirect/from-page/+page.svelte | 8 +++++++ .../remote/query-redirect/redirect.remote.js | 14 +++++++++++++ .../query-redirect/redirected/+page.svelte | 1 + packages/kit/test/apps/basics/test/test.js | 21 +++++++++++++++++++ 12 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 .changeset/forty-dots-punch.md create mode 100644 packages/kit/test/apps/basics/src/routes/remote/query-redirect/+page.svelte create mode 100644 packages/kit/test/apps/basics/src/routes/remote/query-redirect/from-common-layout/+layout.svelte create mode 100644 packages/kit/test/apps/basics/src/routes/remote/query-redirect/from-common-layout/+page.svelte create mode 100644 packages/kit/test/apps/basics/src/routes/remote/query-redirect/from-common-layout/redirected/+page.svelte create mode 100644 packages/kit/test/apps/basics/src/routes/remote/query-redirect/from-page/+page.svelte create mode 100644 packages/kit/test/apps/basics/src/routes/remote/query-redirect/redirect.remote.js create mode 100644 packages/kit/test/apps/basics/src/routes/remote/query-redirect/redirected/+page.svelte diff --git a/.changeset/forty-dots-punch.md b/.changeset/forty-dots-punch.md new file mode 100644 index 000000000000..913c626f2140 --- /dev/null +++ b/.changeset/forty-dots-punch.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: enable redirects from queries diff --git a/packages/kit/src/runtime/client/remote-functions/query.svelte.js b/packages/kit/src/runtime/client/remote-functions/query.svelte.js index b7be26ef39eb..4cc9e9e156d4 100644 --- a/packages/kit/src/runtime/client/remote-functions/query.svelte.js +++ b/packages/kit/src/runtime/client/remote-functions/query.svelte.js @@ -83,9 +83,7 @@ export function query_batch(id) { } if (result.type === 'redirect') { - // TODO double-check this await goto(result.location); - await new Promise((r) => setTimeout(r, 100)); throw new Redirect(307, result.location); } diff --git a/packages/kit/src/runtime/client/remote-functions/shared.svelte.js b/packages/kit/src/runtime/client/remote-functions/shared.svelte.js index 7d94374f40b1..08d195c5f3d8 100644 --- a/packages/kit/src/runtime/client/remote-functions/shared.svelte.js +++ b/packages/kit/src/runtime/client/remote-functions/shared.svelte.js @@ -21,13 +21,7 @@ export async function remote_request(url) { const result = /** @type {RemoteFunctionResponse} */ (await response.json()); if (result.type === 'redirect') { - // resource_cache.delete(cache_key); - // version++; - // await goto(result.location); - // /** @type {Query} */ (resource).refresh(); - // TODO double-check this await goto(result.location); - await new Promise((r) => setTimeout(r, 100)); throw new Redirect(307, result.location); } diff --git a/packages/kit/src/runtime/server/remote.js b/packages/kit/src/runtime/server/remote.js index cbd843af6c72..d2cd2f192d18 100644 --- a/packages/kit/src/runtime/server/remote.js +++ b/packages/kit/src/runtime/server/remote.js @@ -117,8 +117,8 @@ async function handle_remote_call_internal(event, state, options, manifest, id) } const form_data = await event.request.formData(); - form_client_refreshes = JSON.parse( - /** @type {string} */ (form_data.get('sveltekit:remote_refreshes')) ?? '[]' + form_client_refreshes = /** @type {string[]} */ ( + JSON.parse(/** @type {string} */ (form_data.get('sveltekit:remote_refreshes')) ?? '[]') ); form_data.delete('sveltekit:remote_refreshes'); @@ -129,7 +129,7 @@ async function handle_remote_call_internal(event, state, options, manifest, id) /** @type {RemoteFunctionResponse} */ ({ type: 'result', result: stringify(data, transport), - refreshes: await serialize_refreshes(/** @type {string[]} */ (form_client_refreshes)) + refreshes: await serialize_refreshes(form_client_refreshes) }) ); } @@ -194,7 +194,7 @@ async function handle_remote_call_internal(event, state, options, manifest, id) * @param {string[]} client_refreshes */ async function serialize_refreshes(client_refreshes) { - const refreshes = /** @type {Record>} */ (state.refreshes); + const refreshes = state.refreshes ?? {}; for (const key of client_refreshes) { if (refreshes[key] !== undefined) continue; diff --git a/packages/kit/test/apps/basics/src/routes/remote/query-redirect/+page.svelte b/packages/kit/test/apps/basics/src/routes/remote/query-redirect/+page.svelte new file mode 100644 index 000000000000..2cf96c388267 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/remote/query-redirect/+page.svelte @@ -0,0 +1,2 @@ +from page +from layout diff --git a/packages/kit/test/apps/basics/src/routes/remote/query-redirect/from-common-layout/+layout.svelte b/packages/kit/test/apps/basics/src/routes/remote/query-redirect/from-common-layout/+layout.svelte new file mode 100644 index 000000000000..dbfd19f02d29 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/remote/query-redirect/from-common-layout/+layout.svelte @@ -0,0 +1,13 @@ + + + +{#await layoutRedirect(page.url.pathname) then path} +

on page {path} (== {page.url.pathname})

+{/await} + +{@render children()} diff --git a/packages/kit/test/apps/basics/src/routes/remote/query-redirect/from-common-layout/+page.svelte b/packages/kit/test/apps/basics/src/routes/remote/query-redirect/from-common-layout/+page.svelte new file mode 100644 index 000000000000..9d65b32980e5 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/remote/query-redirect/from-common-layout/+page.svelte @@ -0,0 +1 @@ +

should never see this

diff --git a/packages/kit/test/apps/basics/src/routes/remote/query-redirect/from-common-layout/redirected/+page.svelte b/packages/kit/test/apps/basics/src/routes/remote/query-redirect/from-common-layout/redirected/+page.svelte new file mode 100644 index 000000000000..a0164f2662b3 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/remote/query-redirect/from-common-layout/redirected/+page.svelte @@ -0,0 +1 @@ +

redirected

diff --git a/packages/kit/test/apps/basics/src/routes/remote/query-redirect/from-page/+page.svelte b/packages/kit/test/apps/basics/src/routes/remote/query-redirect/from-page/+page.svelte new file mode 100644 index 000000000000..fa4783f66c60 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/remote/query-redirect/from-page/+page.svelte @@ -0,0 +1,8 @@ + + + +{#await pageRedirect() then _} +

should never see this

+{/await} diff --git a/packages/kit/test/apps/basics/src/routes/remote/query-redirect/redirect.remote.js b/packages/kit/test/apps/basics/src/routes/remote/query-redirect/redirect.remote.js new file mode 100644 index 000000000000..e399ff56554b --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/remote/query-redirect/redirect.remote.js @@ -0,0 +1,14 @@ +import { query } from '$app/server'; +import { redirect } from '@sveltejs/kit'; + +export const layoutRedirect = query('unchecked', (path) => { + if (path !== '/remote/query-redirect/from-common-layout/redirected') { + redirect(307, '/remote/query-redirect/from-common-layout/redirected'); + } + + return path; +}); + +export const pageRedirect = query(() => { + redirect(307, '/remote/query-redirect/redirected'); +}); diff --git a/packages/kit/test/apps/basics/src/routes/remote/query-redirect/redirected/+page.svelte b/packages/kit/test/apps/basics/src/routes/remote/query-redirect/redirected/+page.svelte new file mode 100644 index 000000000000..a0164f2662b3 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/remote/query-redirect/redirected/+page.svelte @@ -0,0 +1 @@ +

redirected

diff --git a/packages/kit/test/apps/basics/test/test.js b/packages/kit/test/apps/basics/test/test.js index 36c6ed0ad9d8..5484835aabf0 100644 --- a/packages/kit/test/apps/basics/test/test.js +++ b/packages/kit/test/apps/basics/test/test.js @@ -1600,6 +1600,27 @@ test.describe('remote functions', () => { } }); + test('query redirects on page load (query in common layout)', async ({ + page, + javaScriptEnabled + }) => { + await page.goto('/remote/query-redirect'); + await page.click('a[href="/remote/query-redirect/from-common-layout"]'); + await expect(page.locator('#redirected')).toHaveText('redirected'); + // TODO remove if-condition once async SSR exists + if (javaScriptEnabled) { + await expect(page.locator('#layout-query')).toHaveText( + 'on page /remote/query-redirect/from-common-layout/redirected (== /remote/query-redirect/from-common-layout/redirected)' + ); + } + }); + + test('query redirects on page load (query on page)', async ({ page }) => { + await page.goto('/remote/query-redirect'); + await page.click('a[href="/remote/query-redirect/from-page"]'); + await expect(page.locator('#redirected')).toHaveText('redirected'); + }); + test('form works', async ({ page }) => { await page.goto('/remote/form'); await page.fill('#input-task', 'hi'); From e1ea17075592f59794b9406dfa062a7acb2105a9 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Wed, 10 Sep 2025 14:09:19 +0200 Subject: [PATCH 2/3] async SSR can't come soon enough --- packages/kit/test/apps/basics/test/test.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/kit/test/apps/basics/test/test.js b/packages/kit/test/apps/basics/test/test.js index 5484835aabf0..42390f893728 100644 --- a/packages/kit/test/apps/basics/test/test.js +++ b/packages/kit/test/apps/basics/test/test.js @@ -1604,18 +1604,21 @@ test.describe('remote functions', () => { page, javaScriptEnabled }) => { + // TODO remove once async SSR exists + if (!javaScriptEnabled) return; + await page.goto('/remote/query-redirect'); await page.click('a[href="/remote/query-redirect/from-common-layout"]'); await expect(page.locator('#redirected')).toHaveText('redirected'); - // TODO remove if-condition once async SSR exists - if (javaScriptEnabled) { - await expect(page.locator('#layout-query')).toHaveText( - 'on page /remote/query-redirect/from-common-layout/redirected (== /remote/query-redirect/from-common-layout/redirected)' - ); - } + await expect(page.locator('#layout-query')).toHaveText( + 'on page /remote/query-redirect/from-common-layout/redirected (== /remote/query-redirect/from-common-layout/redirected)' + ); }); test('query redirects on page load (query on page)', async ({ page }) => { + // TODO remove once async SSR exists + if (!javaScriptEnabled) return; + await page.goto('/remote/query-redirect'); await page.click('a[href="/remote/query-redirect/from-page"]'); await expect(page.locator('#redirected')).toHaveText('redirected'); From 58d655ad62f407bc8e43d42bbad619dba0321e0b Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Wed, 10 Sep 2025 14:51:37 +0200 Subject: [PATCH 3/3] oops --- packages/kit/test/apps/basics/test/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kit/test/apps/basics/test/test.js b/packages/kit/test/apps/basics/test/test.js index 42390f893728..6b11c9b15483 100644 --- a/packages/kit/test/apps/basics/test/test.js +++ b/packages/kit/test/apps/basics/test/test.js @@ -1615,7 +1615,7 @@ test.describe('remote functions', () => { ); }); - test('query redirects on page load (query on page)', async ({ page }) => { + test('query redirects on page load (query on page)', async ({ page, javaScriptEnabled }) => { // TODO remove once async SSR exists if (!javaScriptEnabled) return;