Middleware
Server-side request interceptors that run before loaders and API routes. Use them for authentication, redirects, request validation, and context enrichment.
Defining Middleware
Middleware modules live in src/middleware/ and export a middleware function:
src/middleware/auth.ts
import type { MiddlewareFn } from "@pracht/core";
export const middleware: MiddlewareFn = async ({ request }) => {
const session = await getSession(request);
// Redirect unauthenticated users
if (!session) {
return { redirect: "/login" };
}
// Return void to continue to the loader
};Applying Middleware
Register middleware by name in defineApp, then reference them in routes or groups:
src/routes.ts
export const app = defineApp({
middleware: {
auth: "./middleware/auth.ts",
rateLimit: "./middleware/rate-limit.ts",
},
routes: [
// Applied to a single route
route("/profile", "./routes/profile.tsx", { middleware: ["auth"] }),
// Applied to a group โ all children inherit
group({ middleware: ["auth"], shell: "app" }, [
route("/dashboard", "./routes/dashboard.tsx"),
route("/settings", "./routes/settings.tsx"),
]),
],
});Middleware Stacking
Middleware from groups and routes is combined. A route inside a group with ["auth"] that also declares ["rateLimit"] runs both in order:
auth(from group)rateLimit(from route)- Loader / API route
Middleware Results
| Return | Effect |
|---|---|
undefined / void |
Continue to the next middleware or loader |
{ redirect: "/path" } |
HTTP 302 redirect |
{ response: new Response(...) } |
Short-circuit with a custom response |