Repository navigation
fix(query): preserve SSR headers and avoid duplicate cookies - #634
Merged
ryansolid merged 3 commits intoSep 30, 2026
Merged
Conversation
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 detectedLatest commit: d10a3e3 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
Co-authored-by: Cursor <cursoragent@cursor.com> # Conflicts: # src/data/query.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #633.
A query returning or throwing
respond()could give an HTML pageContent-Type: application/json. A rawResponsecould also pass alongContent-Disposition: attachmentand make the browser download the page.The page now keeps its own content headers and cache validators. Use
httpHeader()from@solidjs/webto 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.Locationis 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'swindow.scrollTowarning.@arethetypeswrong/cli --pack . --profile esm-only, Prettier andgit diff --checkpass.