From 4633f0a9e5db161d84f2a052af0a2debe4f15f0a Mon Sep 17 00:00:00 2001 From: "Amir H. Hashemi" <87268103+amirhhashemi@users.noreply.github.com> Date: Wed, 24 Dec 2025 11:40:50 +0330 Subject: [PATCH 1/3] Add a note about using `redirect` with server functions --- .../building-your-application/data-fetching.mdx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/routes/solid-start/building-your-application/data-fetching.mdx b/src/routes/solid-start/building-your-application/data-fetching.mdx index 497499b781..b5ae5566fe 100644 --- a/src/routes/solid-start/building-your-application/data-fetching.mdx +++ b/src/routes/solid-start/building-your-application/data-fetching.mdx @@ -41,3 +41,19 @@ const getCurrentUserQuery = query(async (id: string) => { In this example, the `getCurrentUserQuery` retrieves the session data, and if an authenticated user exists, it gets their information from the database and returns it. Otherwise, it redirects the user to the login page. All of these operations are performed completely on the server regardless of how the query is called. + +:::caution[Redirects and streaming don't mix] +HTTP redirects work by setting a `3xx` status code on the response. +Once a response has started streaming, its headers (including the status code) are already sent to the client and cannot be changed, even if the stream hasn't finished yet. + +If a server function attempts to redirect after streaming has begun, you'll encounter the common error: + +**"Cannot set headers after they are sent to the client."** + +To avoid this, disable streaming for queries that may perform a redirect by enabling the [`deferStream`](/solid-router/reference/data-apis/create-async#deferstream) option. + +```tsx +const user = createAsync(() => getCurrentUserQuery(), { deferStream: true }); +``` + +::: From 89ee441d506a9c7c6334be3ec398029fe4748e40 Mon Sep 17 00:00:00 2001 From: "Amir H. Hashemi" <87268103+amirhhashemi@users.noreply.github.com> Date: Wed, 24 Dec 2025 11:54:19 +0330 Subject: [PATCH 2/3] update --- .../building-your-application/data-fetching.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/routes/solid-start/building-your-application/data-fetching.mdx b/src/routes/solid-start/building-your-application/data-fetching.mdx index b5ae5566fe..49889f5284 100644 --- a/src/routes/solid-start/building-your-application/data-fetching.mdx +++ b/src/routes/solid-start/building-your-application/data-fetching.mdx @@ -42,15 +42,15 @@ In this example, the `getCurrentUserQuery` retrieves the session data, and if an Otherwise, it redirects the user to the login page. All of these operations are performed completely on the server regardless of how the query is called. -:::caution[Redirects and streaming don't mix] -HTTP redirects work by setting a `3xx` status code on the response. -Once a response has started streaming, its headers (including the status code) are already sent to the client and cannot be changed, even if the stream hasn't finished yet. +:::caution[Modifying headers after streaming] +Once a response starts streaming, its headers (including the status code and cookies) are immediately sent to the client and **cannot be modified**. -If a server function attempts to redirect after streaming has begun, you'll encounter the common error: +Any server-side operation that changes headers, such as performing a redirect (`3xx` status) or using APIs like `useSession` that modify cookies, must happen **before** streaming begins. +Otherwise, you'll encounter errors like: **"Cannot set headers after they are sent to the client."** -To avoid this, disable streaming for queries that may perform a redirect by enabling the [`deferStream`](/solid-router/reference/data-apis/create-async#deferstream) option. +To avoid this, disable streaming for queries that may modify headers by enabling the [`deferStream`](/solid-router/reference/data-apis/create-async#deferstream) option. ```tsx const user = createAsync(() => getCurrentUserQuery(), { deferStream: true }); From 5dcda3cbc5e65b4eed095fb2e18ead7bd9edfe30 Mon Sep 17 00:00:00 2001 From: "Amir H. Hashemi" <87268103+amirhhashemi@users.noreply.github.com> Date: Sun, 28 Dec 2025 10:35:18 +0330 Subject: [PATCH 3/3] update --- .../solid-start/building-your-application/data-fetching.mdx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/routes/solid-start/building-your-application/data-fetching.mdx b/src/routes/solid-start/building-your-application/data-fetching.mdx index 49889f5284..17e5fdb082 100644 --- a/src/routes/solid-start/building-your-application/data-fetching.mdx +++ b/src/routes/solid-start/building-your-application/data-fetching.mdx @@ -43,10 +43,8 @@ Otherwise, it redirects the user to the login page. All of these operations are performed completely on the server regardless of how the query is called. :::caution[Modifying headers after streaming] -Once a response starts streaming, its headers (including the status code and cookies) are immediately sent to the client and **cannot be modified**. - -Any server-side operation that changes headers, such as performing a redirect (`3xx` status) or using APIs like `useSession` that modify cookies, must happen **before** streaming begins. -Otherwise, you'll encounter errors like: +Once streaming begins, response headers (including status and cookies) are sent and cannot be changed. +Any header-modifying logic within a server function, such as redirects or APIs like `useSession` that set cookies, must run before streaming starts, or this error will occur: **"Cannot set headers after they are sent to the client."**