Navigated to /docs/getting-started/middleware

Middleware

Run fast request-aware checks before route loading and keep authentication data scoped to the active request.

Use middleware to control route flow

Middleware runs before loaders and rendering. It can allow navigation or redirect to another same-origin path with an optional redirect status. Use it for fast routing decisions rather than slow page data.

  • Use page middleware when the check belongs to one route.

  • Use layout middleware when descendants share the check.

  • Register plugin middleware for application-wide integration behavior.

  • Prefer hosting or platform redirect rules for unconditional redirects that do not need application request data.

Keep session checks on the server

defineServerMiddleware prevents the check from running during browser navigation. It is the right boundary for HttpOnly cookies, server sessions, private clients, and permission prechecks.

Because it is skipped during SPA navigation, server-only middleware is not a client navigation gate. Pair it with safe hydrated auth state or client navigation handling, and keep the real authorization check in every protected loader, action, and server route.

Create src/pages/account.tsx

TSX
tsximport { defineServerMiddleware } from "@tavojs/core/router";
import { Page, Text } from "@tavojs/ui";

export const middleware = defineServerMiddleware(async ({ request }) => {
  const { readSession } = await import("./session.server");
  const session = await readSession(request);
  if (!session) return { redirect: "/login" };
});

export default function AccountPage() {
  return (
    <Page>
      <Text>Account</Text>
    </Page>
  );
}

Know which middleware guards each entry path

Entry pathPage middlewareServer-only middlewareFinal authorization
Direct SSR requestRunsRunsRepeat in loader or action
HydrationUses resolved route stateDoes not rerunUse only safe serialized identity
Later SPA navigationRunsSkippedProtected loader or endpoint decides
Direct action or API requestNot a security boundaryDepends on registered request pipelineAction or handler must enforce it

Keep request data request-scoped

Read headers, cookies, and the URL from the supplied context. Pass only safe derived values through loader results or server services designed for the active request. Do not write the current user into a global store or module variable.

Keep middleware fast and abortable

Middleware receives the navigation AbortSignal. Pass it to downstream work and stop promptly when navigation changes. Move route-critical data into a loader and avoid remote calls in middleware when a local cookie or claim is enough for the routing decision.

Checkpoint

Next steps