Repository navigation
Move the Flight rewriter into the Next.js module - #1381
Open
jwrosewell wants to merge 39 commits into
Open
jwrosewell wants to merge 39 commits into
jwrosewell wants to merge 39 commits into
Conversation
Core rewrote the addresses in a React Server Components Flight stream by its media type, in a module of its own, and the publisher path named text/x-component to run it in place of the plain replacement it makes in any other text body. That was the one piece of a framework's handling left in core. The rewriter moves to crates/framework/nextjs as the fetch middleware framework.nextjs.flight, registered with the module and run where a [[fetch]] entry for text/x-component names it. Core knows nothing of Flight, and text/x-component is a media type an entry may cover, as every other text type is. A plain replacement in a length prefixed row leaves the old length, so the middleware says with Middleware::moves_origin_address that it moves the origin's address itself, and core leaves the addresses in a body of the media types such a middleware handles to it, whether or not an entry names it. With the module selected and no entry, a Flight response passes through as the origin sent it. The registry answers that question for a media type, and the publisher path's text pass skips its replacer on that answer. The middleware works from the origin host and the reader's host and scheme its context carries, as the module's HTML middleware does, so a folder in the origin's address stays in a rewritten address. The stock middleware list, the configuration guide, the Next.js guide, the RSC hydration guide, the template and the module's recorded page settings carry the entry, and the design page records the change.
…ement and its rollout Review round 1 found that the design called the middleware's rewriting the same as before and the same as core's plain replacement, when the middleware matches the origin host alone. The design now states the four differences and why, the alternatives to the new method, the adapters, the refusals, consent, failure and the rollout order. It also asks the reviewer what a deployment that does not select the module should get, lists the cases no test covers and records the review round. The template comment counts the three entries it now shows.
Review round 2 approved the design with no blocking issues and found four small errors. The hostname boundary rule holds only for a bare host, because a longer name that begins with the origin host after https://, http:// or // is changed by core's replacement, the old rewriter and the middleware alike. The path paragraph now says that settings validation checks a path and that the entry with the longest path makes an empty document where several cover a request. The template comment limits the order that ts audit writes to the HTML entries, and the review log and revision record carry the round.
jwrosewell
added this pull request to stack #1401
October 15, 2026 17:56
jwrosewell
removed this pull request from stack #1401
October 15, 2026 20:51
…t again The Flight middleware moved the origin's address in a row with three replacements in a row, for the `https://`, `http://` and protocol-relative spellings, and then looked for a bare host at hostname boundaries. Each read the previous one's output. When the request host begins with the origin host, a later spelling matched inside an earlier replacement and the rest of the request host was written again. With `publisher.example` served as `publisher.example.localhost` over `http`, `https://publisher.example/news` came out as `http://publisher.example.localhost.localhost.localhost/news`, and served as `publisher.example:8443` over `https` it came out as `https://publisher.example:8443:8443/news`. `rewrite_utf8_bytes` now finds each occurrence of the origin host once, from the start. One that follows `https://`, `http://` or `//` is moved together with that spelling, and the text between those addresses is given to `rewrite_bare_host_at_boundaries` for a bare host, so nothing written is read again. The three origin spellings the rewriter kept are removed, and an empty origin host leaves the row as it came. The tests check that a request host which begins with the origin host, as a `.localhost` name or with a port, is written once in a `T` row and a newline row over both schemes, that a hyphenated host and a `www.` host over an apex origin are written as before with a longer name left alone, and the rewrite on its own, with an empty origin host.
This was referenced Oct 17, 2026
jwrosewell
added this pull request to stack #1408
October 17, 2026 09:05
jwrosewell
added this pull request to stack #1418
October 19, 2026 12:18
jwrosewell
removed this pull request from stack #1418
October 19, 2026 16:30
jwrosewell
added this pull request to stack #1421
October 19, 2026 17:38
jwrosewell
removed this pull request from stack #1421
October 19, 2026 18:29
jwrosewell
added this pull request to stack #1422
October 19, 2026 19:20
jwrosewell
marked this pull request as ready for review
October 19, 2026 20:24
This branch has not been deployed
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.
Summary
Changes
crates/framework/nextjscrates/trusted-server-core/srcdocs/superpowersdocs/guidecrates/trusted-server-modules/srctrusted-server.example.tomlCHANGELOG.mdcrates/trusted-server-core/README.mdCloses
Closes #1340
Spec
Spec: rsc-flight-middleware
Test plan
CI on this pull request at 61de267 passed all 29 checks.
cargo test-fastly && cargo test-axumcargo clippy-fastly && cargo clippy-axumcargo fmt --all -- --checkcd crates/trusted-server-js/lib && npx vitest runcd crates/trusted-server-js/lib && npm run formatcd docs && npm run formatcargo build --package trusted-server-adapter-fastly --release --target wasm32-wasip1fastly compute serveChecklist
unwrap()in production code (clippy deniesunwrap_usedin CI)logmacros as AGENTS.md asks (notprintln!)On top of the source module series (#1380). Issue: #1340.
What this adds
What changes.
The React Server Components Flight rewriter leaves core for the Next.js module.
crates/trusted-server-core/src/rsc_flight.rsis nowcrates/framework/nextjs/src/flight.rs, the fetch middlewareframework.nextjs.flightfor the media typetext/x-component, registered besideframework.nextjswhenever[framework] module = "nextjs"selects the module and run where a[[fetch]]entry names it for that media type.How it works.
text/x-component, and the rewriter's five tests moved with it.Middleware::moves_origin_address, false by default, and the publisher's text pass leaves that media type to it, whether or not an entry names the middleware, so a Flight response without an entry passes through as the origin sent it.https://hostandhttp://hostfrom the origin host it is given, as the module's HTML rewriting does, so an origin whose address has a folder keeps that folder in a rewritten address.Why
Every framework's code leaves core, and the stack gave a middleware a media type so that a change to a text response has a place. This was the last page change that predated it.
What breaks
A deployment that fronts a Next.js site names the rewriter in a
[[fetch]]entry fortext/x-component, as the guide shows. Without the module selected, a Flight response takes core's plain text handling, where core used to rewrite Flight for everyone.trusted_server_core::rsc_flightis gone.The commits