Skip to main content
better-router uses Hono middleware. A middleware is (c, next) => void | Promise<void>. Order on each request:
  1. Request ALS context (getEnv() needs this)
  2. Global files in src/middleware (sorted by file name)
  3. Nested _middleware.ts from the matched route folder
  4. Per-route middleware export or defineHandler(...) extras
  5. Loader / action / HTTP handler

Global middleware

Files in src/middleware run on every request, including /api/*. Numeric prefixes control order.
src/middleware/01.logger.ts
Any hono/* helper works. Install hono in the app and import it:
src/middleware/02.cors.ts
You usually do not need CORS for same-origin <Form> and <Link>. Add it when a separate frontend or mobile app calls /api.

Nested middleware

src/routes/admin/_middleware.ts applies to /admin/*. Use it to gate a whole tree:
src/routes/app/_middleware.ts
That throws 401 for unsigned-in users. For HTML dashboards, a layout loader that redirect("/login") is usually the better UX — see Errors.

Per-route middleware

Pass Hono middleware to defineHandler before the handler:
Pages can export middleware from .server.tsx:

Context variables

src/middleware/00.request-id.ts
Handlers then call c.get("requestId") with the right type.