(c, next) => void | Promise<void>.
Order on each request:
- Request ALS context (
getEnv()needs this) - Global files in
src/middleware(sorted by file name) - Nested
_middleware.tsfrom the matched route folder - Per-route
middlewareexport ordefineHandler(...)extras - Loader / action / HTTP handler
Global middleware
Files insrc/middleware run on every request, including /api/*. Numeric prefixes control order.
src/middleware/01.logger.ts
hono/* helper works. Install hono in the app and import it:
src/middleware/02.cors.ts
<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
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 todefineHandler before the handler:
middleware from .server.tsx:
Context variables
src/middleware/00.request-id.ts
c.get("requestId") with the right type.