From c1334bac6939cd09e31e4220b579a6c899fe4254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vitor=20Hil=C3=A1rio?= Date: Tue, 3 Mar 2026 17:38:53 -0300 Subject: [PATCH 1/5] docs(start): add dynamic middleware section with authorization example --- .../start/framework/react/guide/middleware.md | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/docs/start/framework/react/guide/middleware.md b/docs/start/framework/react/guide/middleware.md index 414316e98e..731b4b8c26 100644 --- a/docs/start/framework/react/guide/middleware.md +++ b/docs/start/framework/react/guide/middleware.md @@ -758,3 +758,80 @@ Middleware functionality is tree-shaken based on the environment for each bundle - On the server, nothing is tree-shaken, so all code used in middleware will be included in the server bundle. - On the client, all server-specific code is removed from the client bundle. This means any code used in the `server` method is always removed from the client bundle. `data` validation code will also be removed. + +## Dynamic Middleware + +Static middlewares are created once and reused across routes. Dynamic middleware wraps that creation in a function, allowing it to accept parameters and behave differently depending on the caller's needs. Authorization is a common use case. + +**Authentication (Static Base Middleware) Example:** + +This middleware validates the session and injects it into `context` for downstream middlewares. + +```tsx +// middleware.ts +import { createMiddleware } from '@tanstack/react-start'; +import { auth } from './my-auth'; + +export const authMiddleware = createMiddleware().server( + async ({ next, request }) => { + const session = await auth.getSession({ headers: request.headers }); + + if (!session) { + throw new Error('Unauthorized'); + } + + return await next({ + context: { session }, + }); + }, +); +``` + +**Authorization (Dynamic Middleware) Example:** + +The middleware validates access based on the dynamic `permissions` parameter, composing with `authMiddleware` so `context.session` is already available. + +```tsx +// middleware.ts +import { createMiddleware } from '@tanstack/react-start'; +import { auth } from './my-auth'; + +export const authMiddleware = createMiddleware().server( + //... +); + +type Permissions = Record; + +export function authorizationMiddleware(permissions: Permissions) { + return createMiddleware({ type: 'function' }) + .middleware([authMiddleware]) + .server(async ({ next, context }) => { + const granted = await auth.hasPermission(context.session, permissions); + + if (!granted) { + throw new Error('Forbidden'); + } + + return await next(); + }); +} +``` + +**Usage in a Server Function:** + +Access requirements are defined per server function, without duplicating any middleware logic. + +```tsx +import { createServerFn } from '@tanstack/react-start'; +import { authorizationMiddleware } from './middleware'; + +export const getClients = createServerFn() + .middleware([ + authorizationMiddleware({ + client: ['read'], + }), + ]) + .handler(async ({ context }) => { + return { message: 'The user can read clients.' }; + }); +``` From eb277657605bd394c93d503a9efd8d7374055c5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vitor=20Hil=C3=A1rio?= Date: Tue, 3 Mar 2026 18:39:04 -0300 Subject: [PATCH 2/5] docs(start): rename dynamic middleware to middleware factories --- docs/start/framework/react/guide/middleware.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/start/framework/react/guide/middleware.md b/docs/start/framework/react/guide/middleware.md index 731b4b8c26..7af4491472 100644 --- a/docs/start/framework/react/guide/middleware.md +++ b/docs/start/framework/react/guide/middleware.md @@ -759,9 +759,9 @@ Middleware functionality is tree-shaken based on the environment for each bundle - On the server, nothing is tree-shaken, so all code used in middleware will be included in the server bundle. - On the client, all server-specific code is removed from the client bundle. This means any code used in the `server` method is always removed from the client bundle. `data` validation code will also be removed. -## Dynamic Middleware +## Middleware Factories -Static middlewares are created once and reused across routes. Dynamic middleware wraps that creation in a function, allowing it to accept parameters and behave differently depending on the caller's needs. Authorization is a common use case. +Static middlewares are created once and reused across routes. A middleware factory wraps that creation in a function, allowing it to accept parameters and behave differently depending on the caller's needs. Authorization is a common use case. **Authentication (Static Base Middleware) Example:** @@ -787,7 +787,7 @@ export const authMiddleware = createMiddleware().server( ); ``` -**Authorization (Dynamic Middleware) Example:** +**Authorization (Middleware Factory) Example:** The middleware validates access based on the dynamic `permissions` parameter, composing with `authMiddleware` so `context.session` is already available. From 6b1872ee3d15aa0fc4c89634595c9f58472e52c3 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2026 21:43:20 +0000 Subject: [PATCH 3/5] ci: apply automated fixes --- .../start/framework/react/guide/middleware.md | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/docs/start/framework/react/guide/middleware.md b/docs/start/framework/react/guide/middleware.md index 7af4491472..682398e2de 100644 --- a/docs/start/framework/react/guide/middleware.md +++ b/docs/start/framework/react/guide/middleware.md @@ -769,22 +769,22 @@ This middleware validates the session and injects it into `context` for downstre ```tsx // middleware.ts -import { createMiddleware } from '@tanstack/react-start'; -import { auth } from './my-auth'; +import { createMiddleware } from '@tanstack/react-start' +import { auth } from './my-auth' export const authMiddleware = createMiddleware().server( async ({ next, request }) => { - const session = await auth.getSession({ headers: request.headers }); + const session = await auth.getSession({ headers: request.headers }) if (!session) { - throw new Error('Unauthorized'); + throw new Error('Unauthorized') } return await next({ context: { session }, - }); + }) }, -); +) ``` **Authorization (Middleware Factory) Example:** @@ -793,27 +793,28 @@ The middleware validates access based on the dynamic `permissions` parameter, co ```tsx // middleware.ts -import { createMiddleware } from '@tanstack/react-start'; -import { auth } from './my-auth'; +import { createMiddleware } from '@tanstack/react-start' +import { auth } from './my-auth' -export const authMiddleware = createMiddleware().server( +export const authMiddleware = createMiddleware() + .server //... -); + () -type Permissions = Record; +type Permissions = Record export function authorizationMiddleware(permissions: Permissions) { return createMiddleware({ type: 'function' }) .middleware([authMiddleware]) .server(async ({ next, context }) => { - const granted = await auth.hasPermission(context.session, permissions); + const granted = await auth.hasPermission(context.session, permissions) if (!granted) { - throw new Error('Forbidden'); + throw new Error('Forbidden') } - return await next(); - }); + return await next() + }) } ``` @@ -822,8 +823,8 @@ export function authorizationMiddleware(permissions: Permissions) { Access requirements are defined per server function, without duplicating any middleware logic. ```tsx -import { createServerFn } from '@tanstack/react-start'; -import { authorizationMiddleware } from './middleware'; +import { createServerFn } from '@tanstack/react-start' +import { authorizationMiddleware } from './middleware' export const getClients = createServerFn() .middleware([ @@ -832,6 +833,6 @@ export const getClients = createServerFn() }), ]) .handler(async ({ context }) => { - return { message: 'The user can read clients.' }; - }); + return { message: 'The user can read clients.' } + }) ``` From 30a129f6a13dc79ff05df1ebdbcce31fe3fed6ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vitor=20Hil=C3=A1rio?= Date: Tue, 3 Mar 2026 18:56:52 -0300 Subject: [PATCH 4/5] docs(start): fix authMiddleware snippet in authorization example under middleware factories --- docs/start/framework/react/guide/middleware.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/start/framework/react/guide/middleware.md b/docs/start/framework/react/guide/middleware.md index 682398e2de..fe4dfbc1c4 100644 --- a/docs/start/framework/react/guide/middleware.md +++ b/docs/start/framework/react/guide/middleware.md @@ -797,9 +797,9 @@ import { createMiddleware } from '@tanstack/react-start' import { auth } from './my-auth' export const authMiddleware = createMiddleware() - .server - //... - () + .server(async ({ next, request }) => { + // ... (implementation from authentication example above) + }) type Permissions = Record From e251ac87868c7baad14bd4db5647d8821e83db74 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Thu, 5 Mar 2026 18:41:17 +0000 Subject: [PATCH 5/5] ci: apply automated fixes --- docs/start/framework/react/guide/middleware.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/start/framework/react/guide/middleware.md b/docs/start/framework/react/guide/middleware.md index fe4dfbc1c4..f296f13fe3 100644 --- a/docs/start/framework/react/guide/middleware.md +++ b/docs/start/framework/react/guide/middleware.md @@ -796,10 +796,11 @@ The middleware validates access based on the dynamic `permissions` parameter, co import { createMiddleware } from '@tanstack/react-start' import { auth } from './my-auth' -export const authMiddleware = createMiddleware() - .server(async ({ next, request }) => { +export const authMiddleware = createMiddleware().server( + async ({ next, request }) => { // ... (implementation from authentication example above) - }) + }, +) type Permissions = Record