-
Notifications
You must be signed in to change notification settings - Fork 80
Open
Labels
1.xIssues planned for a minor release after 1.0Issues planned for a minor release after 1.0
Description
Problem
renderToStream is fundamentally designed for generating an HTML stream. It is not designed to handle the full lifecycle of a RedwoodSDK app route (which requires negotiating between HTML and RSC responses).
Trying to force renderToStream to handle RSC requests breaks its contract and confuses the user consumption model (stream vs response headers).
Instead of patching renderToStream, we need a new API (e.g., renderToResponse) that encapsulates the entire response generation logic (negotiating Content-Type and body format).
Proposed Solution
Introduce a new high-level helper: renderToResponse.
export function renderToResponse(
element: ReactElement,
options: RenderOptions
): Promise<Response>This helper will:
- Accept the component tree and standard options (Document, requestInfo, etc.).
- Inspect
requestInfoto determine if the request is an RSC request (Action or Client Transition). - If RSC Request:
- Generate the raw RSC stream (including Action results).
- Return a
ResponsewithContent-Type: text/x-component.
- If HTML Request:
- Generate the HTML stream (with injected RSC payload).
- Return a
ResponsewithContent-Type: text/html.
This gives us
- Safe Default: Users get the correct behavior for both initial loads and interactivity without manual configuration.
- DRY: This logic is currently embedded in internal logic for
defineApp. Extracting it to a public helper allows "manual" routes to have feature parity with standardrender()routes. - Clear API Boundary:
renderToStreamremains a low-level primitive for "give me HTML", whilerenderToResponsebecomes the standard for "render this page" when users need to do so programmatically/imperatively instead of the default declarativeroute()API.
Example Usage
// worker.tsx
route("/my-custom-route", async (requestInfo) => {
// Before: Crashes on interaction
// return new Response(await renderToStream(<MyPage />, { Document }), { ... });
// After: Works with Actions/Transitions
return renderToResponse(<MyPage />, { Document, requestInfo });
});Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
1.xIssues planned for a minor release after 1.0Issues planned for a minor release after 1.0