Skip to content

fix: serialize query values seeded with .set() during SSR - #16428

Closed
Nic-Polumeyv wants to merge 3 commits into
sveltejs:version-3from
Nic-Polumeyv:fix-query-set-ssr-serialization
Closed

fix: serialize query values seeded with .set() during SSR#16428
Nic-Polumeyv wants to merge 3 commits into
sveltejs:version-3from
Nic-Polumeyv:fix-query-set-ssr-serialization

Conversation

@Nic-Polumeyv

@Nic-Polumeyv Nic-Polumeyv commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

closes #16384

During SSR, calling otherQuery(arg).set(value) inside a query populates the request cache but never reaches the serialized payload, so the client refetches data the server already had. The same call during a client-initiated request is included in the endpoint response and reused without a network call.

The cause is the !event.isRemoteRequest guard in the refresh() helper. It was added in #15803 for non-enhanced form submissions, where refreshing queries is pointless because the page re-renders. At that time .set() outside a form/command threw, so the guard could not affect queries. #15991 removed that error as part of the serialization rework, which made .set() inside queries legal and serialized on the endpoint path, while the SSR render path still hit the old guard and silently dropped the registration.

The render already serializes state.remote.explicit and the client already seeds its cache from the SSR payload, so the fix narrows the guard to the case #15803 actually targeted, a form or command running outside a remote request. Non-enhanced form submissions behave as before, including the noop refresh test added in #15803.

Two side effects of the narrowed guard, both consistent with the endpoint path but worth ruling on knowingly. .set() and .refresh() called from a server or universal load during SSR now also serialize. The SSR payload gains r: true when explicit entries exist, which the client start code ignores.

Tests mirror the reporter's reproduction. A list query seeds per-item detail queries, the server test asserts the seeded values appear in the SSR HTML, and the client test asserts a client-side navigation renders the seeded value with zero remote requests.


Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.

Tests

  • Run the tests with pnpm test and lint the project with pnpm lint and pnpm check

Changesets

  • If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpm changeset and following the prompts. Changesets that add features should be minor and those that fix bugs should be patch. Please prefix changeset messages with feat:, fix:, or chore:.

Edits

  • Please ensure that 'Allow edits from maintainers' is checked. PRs without this option may be closed.

@pkg-svelte-dev

pkg-svelte-dev Bot commented Jul 19, 2026

Copy link
Copy Markdown

Install the latest version of @sveltejs/kit from 9f76db6:

pnpm add https://pkg.svelte.dev/@sveltejs/kit/c/9f76db683092ff9ee32ceb68926b705ca40e95d6

Open in pkg.svelte.dev: https://pkg.svelte.dev/repos/kit/pr/16428

Note

This PR is from a fork. A maintainer must approve approve each commit before it can be built and installed.

@changeset-bot

changeset-bot Bot commented Jul 19, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9f76db6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@sveltejs/kit Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@Nic-Polumeyv
Nic-Polumeyv force-pushed the fix-query-set-ssr-serialization branch from db7a708 to 9f76db6 Compare July 19, 2026 19:19
@Nic-Polumeyv
Nic-Polumeyv changed the base branch from main to version-3 July 19, 2026 19:19
@Nic-Polumeyv
Nic-Polumeyv marked this pull request as ready for review July 19, 2026 20:00
@elliott-with-the-longest-name-on-github

Copy link
Copy Markdown
Contributor

In reviewing this I realized we weren't handling refreshes correctly in the first place: #16461

elliott-with-the-longest-name-on-github added a commit that referenced this pull request Jul 22, 2026
Supersedes #16428. It had the right approach, but we were actually
handling `refresh` wrong in the first place. I thought we'd implemented
this behavior but somehow we haven't.

Anyway, this kills two birds with one stone:
- It makes sure we allow `.refresh` (and `.set`) to run during render
- It makes `.refresh` lazy: Calling `.refresh` busts the cache and
guarantees that the cache will be populated by the end of the request.
If you `await` the query or access its data, it will immediately run and
populate the cache; otherwise SvelteKit will do it at the end of the
request, in parallel with any other refreshing queries
@Nic-Polumeyv
Nic-Polumeyv deleted the fix-query-set-ssr-serialization branch July 30, 2026 22:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Query .set()ing other query responses not serialized during SSR

2 participants