Skip to content

fix(query): preserve SSR headers and avoid duplicate cookies - #634

Merged
ryansolid merged 3 commits into
solidjs:nextfrom
everton-dgn:fix/query-ssr-response-headers
Sep 30, 2026
Merged

ryansolid merged 3 commits into
solidjs:nextfrom
everton-dgn:fix/query-ssr-response-headers

Conversation

@everton-dgn

@everton-dgn everton-dgn commented Sep 29, 2026 •

Copy link
Copy Markdown

Closes #633.

A query returning or throwing respond() could give an HTML page Content-Type: application/json. A raw Response could also pass along Content-Disposition: attachment and make the browser download the page.

The page now keeps its own content headers and cache validators. Use httpHeader() from @solidjs/web to set these headers on the page itself.

Cookies still pass through, but reading the same cached result again no longer appends them a second time. A new result, including one supplied through query.set(), can still update the cookie. Location is left alone so redirects keep working after streaming starts.

The 24 server regression tests cover returned and thrown responses, concurrent reads, cache updates and streaming redirects. They also check the rendered page's headers.

Validation:

  • pnpm test: 442 client tests, 62 server tests and the test typecheck pass. The client suite still logs jsdom's window.scrollTo warning.
  • TypeScript/Rollup build and the filesystem bundle gate pass.
  • @arethetypeswrong/cli --pack . --profile esm-only, Prettier and git diff --check pass.

Closes solidjs#633.

When a query returned or threw a `respond()` envelope during SSR, its `Content-Type: application/json` replaced the HTML document's content type. The browser then displayed the HTML as text.

Skip `Content-Type`, `Content-Length`, `Content-Encoding` and `Transfer-Encoding` when copying query headers to the request event, for both envelopes and plain `Response` values. Preserve cookies, other metadata and redirect handling. The change deliberately leaves late `Location` writes intact: the streaming runtime uses them to emit its redirect fallback after the shell has been sent.

Includes a patch changeset and 13 server tests covering returned/thrown results, raw responses, synchronous reads, the rendered document response, multiple cookies, cached reads after commit, and redirects before and after the streaming shell.

Validation:

- Reproduced seven regression failures before the fix; all 13 new tests pass with it.
- `pnpm test`: 442 client tests, 51 server tests and the test typecheck pass. The client suite emits jsdom's `window.scrollTo` not-implemented messages and exits successfully.
- `pnpm exec tsc` and `pnpm exec rollup -c` pass.
- `scripts/check-fs-gate.mjs` assertions pass, with only temporary-directory cleanup redirected to the trash.
- `pnpm dlx @arethetypeswrong/cli --pack . --profile esm-only` passes.
- Prettier checks for the three changed files and `git diff --check` pass.
Track cookie forwarding per cached result and document. Repeated reads no
longer append the same cookies, while a new result or query.set can update
them even when it reuses a Response object.

Filter representation metadata such as Content-Disposition and ETag before
copying query headers to the page. Skip header writes when the value is
already present, avoiding late writes for unchanged metadata.

Add coverage for concurrent reads, separate requests and cache replacement.
Update the changeset with a shorter description of the behavior.
@changeset-bot

changeset-bot Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d10a3e3

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

This PR includes changesets to release 1 package
Name Type
@solidjs/router Patch

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

@everton-dgn everton-dgn changed the title fix(query): preserve SSR document body headers fix(query): preserve SSR headers and avoid duplicate cookies Sep 29, 2026
Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	src/data/query.ts
@ryansolid
ryansolid merged commit 2ced482 into solidjs:next Sep 30, 2026
4 checks passed
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.

2 participants