Execution contract
- Use when
- Use when server functions, routes, or requests share logging, auth, context, or timing behavior.
- Avoid when
- Keep one-off business logic in its handler or domain service when it has no cross-cutting reuse.
- Preconditions
- Choose middleware type, order, context input/output, and how next() propagates errors.
- Verification
- Test ordering, short-circuiting, errors, and concurrent requests to ensure per-request context isolation.
- Failure mode
- A skipped handler or missing context usually means next() was not returned, ordering is wrong, or middleware type mismatches.
- Security
- Logging middleware must redact cookies, Authorization, secrets, and sensitive request bodies.
Scope contract
createMiddleware() creates request middleware by default for SSR, Server Routes, and Server Functions. createMiddleware({ type: 'function' }) creates Server Function middleware with validator and client phases. Do not promote a function-local rule to a global request rule merely for reuse.
Chain implementation
Call next to execute downstream code and return its result. Fields added with next({ context }) flow downstream only. An early return should be an intentional rejection or response, not a missing next call.
import { createMiddleware } from '@tanstack/react-start'
export const requestIdMiddleware = createMiddleware()
.server(({ next }) => next({
context: { requestId: crypto.randomUUID() },
}))Security invariants
Client sendContext is untrusted input: validate it on the server and never use it as identity itself. After adding a custom src/start.ts, explicitly retain createCsrfMiddleware. CSRF, input validation, authentication, and resource authorization are separate checks.