You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Allow cancelling React SSR rendering without aborting the response transport
#8917
We want to impose an SSR render budget while the browser remains connected: stop pending React rendering, flush its Suspense fallbacks, and let the router finish streaming hydration data and close the document.
renderRouterToStream currently uses request.signal for both React rendering and transformReadableStreamWithRouter. Aborting it cancels the response transport too. That is appropriate for a disconnected client, but prevents using the same renderer adapter for a render-only deadline.
Would an optional renderer signal be an acceptable API?
request.signal retains its current meaning and cancels the whole response.
renderSignal only stops React; the router serialization/HTML transport keeps draining.
Without renderSignal, behavior stays unchanged.
Disconnecting the client still cancels rendering even when a separate render signal is supplied.
If cancellation happens before React's shell is ready, including an already-aborted signal, reject with the original renderSignal.reason; the application chooses its fallback response and HTTP status.
After shell readiness, let React flush pending-section fallbacks/client-render instructions while Router continues serialization. The signal alone does not select a new HTTP status.
Expected render cancellation should not be logged as a renderer failure; unrelated failures should remain reportable. No new public cancellation-error type is proposed.
The minimal proposal changes only renderRouterToStream. As a possible additive extension, defaultStreamHandler could also accept and forward renderSignal, avoiding a custom render callback at the application boundary. That higher-level convenience is not required by the initial proposal; I would welcome maintainers' preference on it.
The application would still choose its render budget and settle its deferred data sources. Router would provide the rendering-cancellation mechanism; application data loading and retries would remain application-owned.
We observed the shared-signal wiring in @tanstack/react-router@1.170.46 and the same renderer source on main when checked. This is an API proposal, not a claim that cancelling a real request should keep its response alive.
Related but different: #7909 concerns abandoned-stream watchdog expiry, #7674 concerns missing bootstrap data, and #7714 proposes broader per-request streaming policy.
Is renderSignal a reasonable seam, or is there an existing supported way to achieve this without copying the renderer adapter? Would you prefer the minimal renderer option, or also forwarding it through defaultStreamHandler?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
We want to impose an SSR render budget while the browser remains connected: stop pending React rendering, flush its Suspense fallbacks, and let the router finish streaming hydration data and close the document.
renderRouterToStreamcurrently usesrequest.signalfor both React rendering andtransformReadableStreamWithRouter. Aborting it cancels the response transport too. That is appropriate for a disconnected client, but prevents using the same renderer adapter for a render-only deadline.Would an optional renderer signal be an acceptable API?
Proposed semantics:
request.signalretains its current meaning and cancels the whole response.renderSignalonly stops React; the router serialization/HTML transport keeps draining.renderSignal, behavior stays unchanged.renderSignal.reason; the application chooses its fallback response and HTTP status.The minimal proposal changes only
renderRouterToStream. As a possible additive extension,defaultStreamHandlercould also accept and forwardrenderSignal, avoiding a custom render callback at the application boundary. That higher-level convenience is not required by the initial proposal; I would welcome maintainers' preference on it.The application would still choose its render budget and settle its deferred data sources. Router would provide the rendering-cancellation mechanism; application data loading and retries would remain application-owned.
We observed the shared-signal wiring in
@tanstack/react-router@1.170.46and the same renderer source onmainwhen checked. This is an API proposal, not a claim that cancelling a real request should keep its response alive.Related but different: #7909 concerns abandoned-stream watchdog expiry, #7674 concerns missing bootstrap data, and #7714 proposes broader per-request streaming policy.
Is
renderSignala reasonable seam, or is there an existing supported way to achieve this without copying the renderer adapter? Would you prefer the minimal renderer option, or also forwarding it throughdefaultStreamHandler?AI-assisted proposal.
All reactions