- Spec files
npm-tanstack--react-start
Describes: pkg:npm/@tanstack/react-start@1.132.x
- Description
- Modern full-stack React framework with SSR, streaming, server functions, and API routes powered by TanStack Router and Vite.
- Author
- tessl
- Last updated
How to use
npx @tessl/cli registry install tessl/npm-tanstack--react-start@1.132.0
middleware.md docs/
1# Middleware23The middleware system provides composable functions for server functions to handle validation, authentication, logging, and other cross-cutting concerns. Middleware can be chained together and applied to server functions for enhanced functionality.45## Capabilities67### Create Middleware89Creates middleware that can be applied to server functions for request/response processing.1011```typescript { .api }12/**13* Creates middleware with optional configuration14* @param options - Configuration options including middleware type15* @returns CreateMiddlewareResult for chaining additional configuration16*/17function createMiddleware<TType extends MiddlewareType>(18options?: { type?: TType }19): CreateMiddlewareResult<{}, TType>;2021interface CreateMiddlewareResult<TRegister, TType> {22/** Add middleware function to the chain */23middleware<T>(middleware: T): CreateMiddlewareResult<TRegister & T, TType>;2425/** Add input validation to the middleware */26inputValidator<T>(validator: T): CreateMiddlewareResult<TRegister & T, TType>;2728/** Add client-side processing */29client<T>(client: T): CreateMiddlewareResult<TRegister & T, TType>;3031/** Add server-side processing */32server<T>(server: T): CreateMiddlewareResult<TRegister & T, TType>;33}3435type MiddlewareType = 'request' | 'function';36```3738**Usage Examples:**3940```typescript41import { createMiddleware, createServerFn } from "@tanstack/react-start";4243// Authentication middleware44const authMiddleware = createMiddleware()45.server(async (input, { request }) => {46const token = request.headers.get('Authorization');47if (!token) throw new Error('Unauthorized');4849const user = await verifyToken(token);50return { ...input, user };51});5253// Validation middleware54const validateUserInput = createMiddleware()55.inputValidator((data: unknown) => {56if (!data || typeof data !== 'object') {57throw new Error('Invalid input');58}59return data as { name: string; email: string };60});6162// Apply middleware to server function63const createUser = createServerFn({ method: 'POST' })64.middleware(authMiddleware)65.middleware(validateUserInput)66.handler(async ({ name, email, user }) => {67// Handler receives validated input + auth context68return await db.user.create({69data: { name, email, createdBy: user.id }70});71});72```7374### Function Middleware7576Middleware specifically designed for server functions with type-safe parameter passing.7778```typescript { .api }79interface FunctionMiddleware<TInput, TOutput, TContext = {}> {80(input: TInput, context: FunctionMiddlewareContext<TContext>):81Promise<TOutput> | TOutput;82}8384interface FunctionMiddlewareContext<T = {}> {85/** Current request object */86request: Request;87/** Response headers */88headers: Headers;89/** Additional context data */90context: T;91/** Continue to next middleware */92next: () => Promise<any>;93}9495interface FunctionMiddlewareOptions<96TRegister,97TResponse,98TMiddlewares,99TInputValidator,100THandler101> {102middleware?: TMiddlewares;103inputValidator?: TInputValidator;104handler?: THandler;105}106```107108**Usage Examples:**109110```typescript111import { createMiddleware } from "@tanstack/react-start";112113// Logging middleware114const logMiddleware = createMiddleware()115.server(async (input, { request, next }) => {116console.log(`[${new Date().toISOString()}] ${request.method} ${request.url}`);117const start = Date.now();118119const result = await next();120121console.log(`Request completed in ${Date.now() - start}ms`);122return result;123});124125// Rate limiting middleware126const rateLimitMiddleware = createMiddleware()127.server(async (input, { request, next }) => {128const ip = request.headers.get('x-forwarded-for') || 'unknown';129const key = `rate-limit:${ip}`;130131const requests = await redis.incr(key);132if (requests === 1) {133await redis.expire(key, 60); // 1 minute window134}135136if (requests > 100) {137throw new Error('Rate limit exceeded');138}139140return await next();141});142```143144### Request Middleware145146Middleware that operates at the request level before server functions are invoked.147148```typescript { .api }149interface RequestMiddleware<TContext = {}> {150(request: Request, context: RequestMiddlewareContext<TContext>):151Promise<Response | void> | Response | void;152}153154interface RequestMiddlewareContext<T = {}> {155/** Additional context data */156context: T;157/** Continue to next middleware */158next: () => Promise<Response>;159}160161interface RequestMiddlewareOptions<162TRegister,163TMiddlewares,164TServer165> {166type: 'request';167middleware?: TMiddlewares;168server?: TServer;169}170```171172### Middleware Utilities173174Helper functions for working with middleware chains and validation.175176```typescript { .api }177/**178* Flattens nested middleware arrays into a single array179* @param middlewares - Array of middleware to flatten180* @returns Flattened middleware array181*/182function flattenMiddlewares(183middlewares: AnyFunctionMiddleware[]184): AnyFunctionMiddleware[];185186/**187* Executes a middleware chain188* @param middlewares - The middleware chain to execute189* @param context - The execution context190* @returns Result of middleware execution191*/192function executeMiddleware<T>(193middlewares: AnyFunctionMiddleware[],194context: T195): Promise<T>;196197/**198* Apply middleware to a function199* @param middleware - The middleware to apply200* @param fn - The function to wrap with middleware201* @returns Enhanced function with middleware202*/203function applyMiddleware<T>(204middleware: AnyFunctionMiddleware[],205fn: T206): T;207208/**209* Execute validation logic210* @param validator - The validator to execute211* @param input - The input to validate212* @returns Validated output213*/214function execValidator<T, U>(215validator: Validator<T, U>,216input: T217): U;218```219220### Middleware Composition221222```typescript { .api }223interface IntersectAllValidatorInputs<T extends ReadonlyArray<any>> {224// Type helper for combining validator inputs225}226227interface IntersectAllValidatorOutputs<T extends ReadonlyArray<any>> {228// Type helper for combining validator outputs229}230231interface AssignAllMiddleware<T extends ReadonlyArray<any>> {232// Type helper for combining middleware types233}234```235236## Advanced Patterns237238### Conditional Middleware239240```typescript241import { createMiddleware } from "@tanstack/react-start";242243const conditionalAuth = createMiddleware()244.server(async (input, { request, next }) => {245const publicPaths = ['/health', '/api/public'];246const path = new URL(request.url).pathname;247248if (publicPaths.includes(path)) {249return await next();250}251252// Apply authentication for protected paths253const token = request.headers.get('Authorization');254if (!token) throw new Error('Authentication required');255256const user = await verifyToken(token);257return { ...input, user };258});259```260261### Error Handling Middleware262263```typescript264import { createMiddleware } from "@tanstack/react-start";265266const errorHandlerMiddleware = createMiddleware()267.server(async (input, { next }) => {268try {269return await next();270} catch (error) {271console.error('Server function error:', error);272273if (error.message === 'Unauthorized') {274throw new Response('Unauthorized', { status: 401 });275}276277throw new Response('Internal Server Error', { status: 500 });278}279});280```281282## Types283284```typescript { .api }285// Middleware type definitions286type MiddlewareType = 'request' | 'function';287288interface AnyFunctionMiddleware {289type: 'function';290middleware: (...args: any[]) => any;291}292293interface AnyRequestMiddleware {294type: 'request';295middleware: (request: Request, context: any) => any;296}297298// Function middleware types299interface FunctionMiddlewareWithTypes<300TRegister,301TResponse,302TMiddlewares,303TInputValidator,304THandler305> {306middleware?: TMiddlewares;307inputValidator?: TInputValidator;308handler?: THandler;309}310311interface FunctionMiddlewareValidator<T, U> {312(input: T): U;313}314315interface FunctionMiddlewareServer<TInput, TOutput> {316(input: TInput, context: ServerFnCtx): Promise<TOutput> | TOutput;317}318319interface FunctionMiddlewareClient<TInput, TOutput> {320(input: TInput): Promise<TOutput> | TOutput;321}322323// Request middleware types324interface RequestMiddlewareWithTypes<325TRegister,326TMiddlewares,327TServer328> {329type: 'request';330middleware?: TMiddlewares;331server?: TServer;332}333334interface RequestServerFn<T> {335(request: Request, context: T): Promise<Response | void> | Response | void;336}337338// Middleware context types339interface FunctionMiddlewareAfterMiddleware<T> {340context: T;341next: () => Promise<any>;342}343344interface RequestMiddlewareAfterMiddleware<T> {345context: T;346next: () => Promise<Response>;347}348349// Validator types350interface Validator<TInput, TOutput> {351(input: TInput): TOutput;352}353354// Context assignment helpers355interface AssignAllClientContextBeforeNext<T extends ReadonlyArray<any>> {356// Type helper for client context assignment357}358359interface FunctionClientResultWithContext<T, U> {360result: T;361context: U;362}363364interface FunctionServerResultWithContext<T, U> {365result: T;366context: U;367}368```