From 6c6ec1b884284774ae2796513ce723171f418b6c Mon Sep 17 00:00:00 2001 From: Egor Fedorov Date: Wed, 31 Dec 2025 23:30:16 +0300 Subject: [PATCH 1/7] demo: use result.response.headers --- examples/react/start-bare/src/data/fn.ts | 31 +++++++++++++++++++ .../react/start-bare/src/routes/index.tsx | 10 ++++++ 2 files changed, 41 insertions(+) create mode 100644 examples/react/start-bare/src/data/fn.ts diff --git a/examples/react/start-bare/src/data/fn.ts b/examples/react/start-bare/src/data/fn.ts new file mode 100644 index 00000000000..ff1b07831dc --- /dev/null +++ b/examples/react/start-bare/src/data/fn.ts @@ -0,0 +1,31 @@ +import { createMiddleware, createServerFn } from '@tanstack/react-start' +import { getResponseHeaders } from '@tanstack/react-start/server' + +// https://tanstack.com/start/latest/docs/framework/react/guide/isr##using-middleware-for-cache-headers +export const cacheMiddleware = createMiddleware().server(async ({ next }) => { + const result = await next() + + console.log({result, response: result.response}) + result.response.headers.set('Cache-Control', 'b') + + return result +}) + +const data = [ + { id: 1, name: 'Teenage Dirtbag', artist: 'Wheatus' }, + { id: 2, name: 'Smells Like Teen Spirit', artist: 'Nirvana' }, + { id: 3, name: 'The Middle', artist: 'Jimmy Eat World' }, + { id: 4, name: 'My Own Worst Enemy', artist: 'Lit' }, + { id: 5, name: 'Fat Lip', artist: 'Sum 41' }, + { id: 6, name: 'All the Small Things', artist: 'blink-182' }, + { id: 7, name: 'Beverly Hills', artist: 'Weezer' }, +] +export const getPunkSongs = createServerFn({ + method: 'GET', +}) + .middleware([cacheMiddleware]) + .handler(async () => { + const headers = getResponseHeaders() + headers.set('Cache-Control', 'a') + return data + }) diff --git a/examples/react/start-bare/src/routes/index.tsx b/examples/react/start-bare/src/routes/index.tsx index 03832940ce2..181fe5f957d 100644 --- a/examples/react/start-bare/src/routes/index.tsx +++ b/examples/react/start-bare/src/routes/index.tsx @@ -1,12 +1,22 @@ import { createFileRoute } from '@tanstack/react-router' +import { getPunkSongs } from '~/data/fn' + export const Route = createFileRoute('/')({ component: RouteComponent, + loader: async () => { + return await getPunkSongs() + }, + // Disable SSR to show the cache headers in cURL requests + ssr: false, }) function RouteComponent() { + const data = Route.useLoaderData() + return (

Hello world!

+
{JSON.stringify(data, null, 2)}
) } From 3b417f685cae7804be0a31db8e0da7e2a9b51b39 Mon Sep 17 00:00:00 2001 From: Egor Fedorov Date: Thu, 1 Jan 2026 12:36:54 +0300 Subject: [PATCH 2/7] demo: use `result.headers` --- examples/react/start-bare/src/data/fn.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/react/start-bare/src/data/fn.ts b/examples/react/start-bare/src/data/fn.ts index ff1b07831dc..de7a60ce071 100644 --- a/examples/react/start-bare/src/data/fn.ts +++ b/examples/react/start-bare/src/data/fn.ts @@ -5,8 +5,8 @@ import { getResponseHeaders } from '@tanstack/react-start/server' export const cacheMiddleware = createMiddleware().server(async ({ next }) => { const result = await next() - console.log({result, response: result.response}) - result.response.headers.set('Cache-Control', 'b') + // @ts-expect-error - headers is not typed, but they are present. + result.headers.set('Cache-Control', 'b') return result }) From af2a919fa5ff63f8757312bcb84cbd283ef6cf88 Mon Sep 17 00:00:00 2001 From: Egor Fedorov Date: Wed, 31 Dec 2025 21:16:41 +0300 Subject: [PATCH 3/7] demo: update `start-bare` example to show `getResponseHeaders` --- examples/react/start-bare/src/data/fn.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/react/start-bare/src/data/fn.ts b/examples/react/start-bare/src/data/fn.ts index de7a60ce071..bc26d0ed33f 100644 --- a/examples/react/start-bare/src/data/fn.ts +++ b/examples/react/start-bare/src/data/fn.ts @@ -5,8 +5,8 @@ import { getResponseHeaders } from '@tanstack/react-start/server' export const cacheMiddleware = createMiddleware().server(async ({ next }) => { const result = await next() - // @ts-expect-error - headers is not typed, but they are present. - result.headers.set('Cache-Control', 'b') + const headers = getResponseHeaders() + headers.set('Cache-Control', 'b') return result }) From 52fc400c50c2b7fb1b9c7df29a4816c36850dd88 Mon Sep 17 00:00:00 2001 From: Egor Fedorov Date: Wed, 31 Dec 2025 21:18:19 +0300 Subject: [PATCH 4/7] docs(react/isr): use `getResponseHeaders` in example --- docs/start/framework/react/guide/isr.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/start/framework/react/guide/isr.md b/docs/start/framework/react/guide/isr.md index 600a282c201..fc04a84ee9c 100644 --- a/docs/start/framework/react/guide/isr.md +++ b/docs/start/framework/react/guide/isr.md @@ -112,12 +112,14 @@ For API routes, you can use middleware to set cache headers: // routes/api/products/$productId.ts import { createFileRoute } from '@tanstack/react-router' import { createMiddleware } from '@tanstack/react-start' +import { getResponseHeaders } from '@tanstack/react-start/server' const cacheMiddleware = createMiddleware().server(async ({ next }) => { const result = await next() // Add cache headers to the response - result.response.headers.set( + const headers = getResponseHeaders() + headers.set( 'Cache-Control', 'public, max-age=3600, stale-while-revalidate=86400', ) From b8002bee304e4aed75ac52692aed04ee37279361 Mon Sep 17 00:00:00 2001 From: Egor Fedorov Date: Thu, 1 Jan 2026 12:52:30 +0300 Subject: [PATCH 5/7] Revert "demo: update `start-bare` example to show `getResponseHeaders`" This reverts commit af2a919fa5ff63f8757312bcb84cbd283ef6cf88. --- examples/react/start-bare/src/data/fn.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/react/start-bare/src/data/fn.ts b/examples/react/start-bare/src/data/fn.ts index bc26d0ed33f..de7a60ce071 100644 --- a/examples/react/start-bare/src/data/fn.ts +++ b/examples/react/start-bare/src/data/fn.ts @@ -5,8 +5,8 @@ import { getResponseHeaders } from '@tanstack/react-start/server' export const cacheMiddleware = createMiddleware().server(async ({ next }) => { const result = await next() - const headers = getResponseHeaders() - headers.set('Cache-Control', 'b') + // @ts-expect-error - headers is not typed, but they are present. + result.headers.set('Cache-Control', 'b') return result }) From cd6204ac9ebb5723bdec79cf23d83213fa26850f Mon Sep 17 00:00:00 2001 From: Egor Fedorov Date: Thu, 1 Jan 2026 12:52:31 +0300 Subject: [PATCH 6/7] Revert "demo: use `result.headers`" This reverts commit 3b417f685cae7804be0a31db8e0da7e2a9b51b39. --- examples/react/start-bare/src/data/fn.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/react/start-bare/src/data/fn.ts b/examples/react/start-bare/src/data/fn.ts index de7a60ce071..ff1b07831dc 100644 --- a/examples/react/start-bare/src/data/fn.ts +++ b/examples/react/start-bare/src/data/fn.ts @@ -5,8 +5,8 @@ import { getResponseHeaders } from '@tanstack/react-start/server' export const cacheMiddleware = createMiddleware().server(async ({ next }) => { const result = await next() - // @ts-expect-error - headers is not typed, but they are present. - result.headers.set('Cache-Control', 'b') + console.log({result, response: result.response}) + result.response.headers.set('Cache-Control', 'b') return result }) From 335443d29228e6b56e2df964dad3ff09965ba70d Mon Sep 17 00:00:00 2001 From: Egor Fedorov Date: Thu, 1 Jan 2026 12:52:31 +0300 Subject: [PATCH 7/7] Revert "demo: use result.response.headers" This reverts commit 6c6ec1b884284774ae2796513ce723171f418b6c. --- examples/react/start-bare/src/data/fn.ts | 31 ------------------- .../react/start-bare/src/routes/index.tsx | 10 ------ 2 files changed, 41 deletions(-) delete mode 100644 examples/react/start-bare/src/data/fn.ts diff --git a/examples/react/start-bare/src/data/fn.ts b/examples/react/start-bare/src/data/fn.ts deleted file mode 100644 index ff1b07831dc..00000000000 --- a/examples/react/start-bare/src/data/fn.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { createMiddleware, createServerFn } from '@tanstack/react-start' -import { getResponseHeaders } from '@tanstack/react-start/server' - -// https://tanstack.com/start/latest/docs/framework/react/guide/isr##using-middleware-for-cache-headers -export const cacheMiddleware = createMiddleware().server(async ({ next }) => { - const result = await next() - - console.log({result, response: result.response}) - result.response.headers.set('Cache-Control', 'b') - - return result -}) - -const data = [ - { id: 1, name: 'Teenage Dirtbag', artist: 'Wheatus' }, - { id: 2, name: 'Smells Like Teen Spirit', artist: 'Nirvana' }, - { id: 3, name: 'The Middle', artist: 'Jimmy Eat World' }, - { id: 4, name: 'My Own Worst Enemy', artist: 'Lit' }, - { id: 5, name: 'Fat Lip', artist: 'Sum 41' }, - { id: 6, name: 'All the Small Things', artist: 'blink-182' }, - { id: 7, name: 'Beverly Hills', artist: 'Weezer' }, -] -export const getPunkSongs = createServerFn({ - method: 'GET', -}) - .middleware([cacheMiddleware]) - .handler(async () => { - const headers = getResponseHeaders() - headers.set('Cache-Control', 'a') - return data - }) diff --git a/examples/react/start-bare/src/routes/index.tsx b/examples/react/start-bare/src/routes/index.tsx index 181fe5f957d..03832940ce2 100644 --- a/examples/react/start-bare/src/routes/index.tsx +++ b/examples/react/start-bare/src/routes/index.tsx @@ -1,22 +1,12 @@ import { createFileRoute } from '@tanstack/react-router' -import { getPunkSongs } from '~/data/fn' - export const Route = createFileRoute('/')({ component: RouteComponent, - loader: async () => { - return await getPunkSongs() - }, - // Disable SSR to show the cache headers in cURL requests - ssr: false, }) function RouteComponent() { - const data = Route.useLoaderData() - return (

Hello world!

-
{JSON.stringify(data, null, 2)}
) }