Middleware

Middleware

Route-level middleware lets you intercept requests before they reach your page or API handler. Use it for authentication, redirects, logging, and validation.

The _middleware.ts convention

Place a _middleware.ts file in any route directory. It runs for all routes in that directory and its subdirectories.

file tree
pages/
_middleware.ts -> runs for all routes
index.tsx
dashboard/
_middleware.ts -> runs only for /dashboard/*
settings.tsx
profile.tsx
admin/
_middleware.ts -> auth check for /admin/*
index.tsx

Middleware context

A middleware function receives an object with params (dynamic route params), request (the original Request), and a next function to continue the chain.

src/pages/_middleware.ts
import type { MiddlewareContext, MiddlewareNext } from "@thexjs/core";export async function middleware(ctx: MiddlewareContext, next: MiddlewareNext) {  console.log(`[${ctx.request.method}] ${ctx.request.url}`);  return next(ctx);}

Auth middleware example

A common use case is checking for an auth cookie and redirecting unauthenticated users.

src/pages/dashboard/_middleware.ts
import type { MiddlewareContext, MiddlewareNext } from "@thexjs/core";export async function middleware(ctx: MiddlewareContext, next: MiddlewareNext) {  const session = ctx.request.cookies.get("session");  if (!session) {    return new Response(null, {      status: 302,      headers: { Location: "/login" },    });  }  const user = await validateSession(session);  if (!user) {    return new Response(null, {      status: 302,      headers: { Location: "/login" },    });  }  ctx.params.user = user;  return next(ctx);}

MiddlewareNext

Call next(ctx) to pass control to the next middleware or the route handler. You can modify ctx.params to enrich the request context for downstream handlers.

Redirect patterns

Return a Response with a 302 status and a Location header to redirect. You can also return JSON responses for API middleware validation errors.

redirect example
// Redirect to loginreturn new Response(null, {  status: 302,  headers: { Location: "/login?redirect=" + ctx.request.url },});// Redirect back after successful authconst url = new URL(ctx.request.url);const redirectTo = url.searchParams.get("redirect") || "/";return new Response(null, {  status: 302,  headers: { Location: redirectTo },});