newX 1.3 — islands to disk, server-mode islands, image proxy

Middleware

Middleware

Route-level middleware lets you intercept page requests before they reach the page 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 a context object with params (dynamic route params) and request (the original Request), plus a next function as the second argument to continue the chain. It returns a Response.

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();}

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.headers.get("cookie");  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" },    });  }  return next();}

MiddlewareNext

Call next() (no arguments) to pass control to the next middleware or the route handler. Any mutations to ctx.params you make before the call flow through to downstream handlers.

Middleware applies to page routes only. API routes (in apiDir) and content routes are dispatched without a middleware chain.

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 },});