Creating a middleware
Before scaffolding anything, check the concern is actually middleware-shaped:
- Response-only — headers, envelopes, error formatting — belongs in the handler, which owns the response. Not a middleware.
- Used once, in one handler — inline it. A middleware earns its keep by being composed across handlers.
Then pick the target by reading the nearest package.json:
name is |
You are writing | Follow |
|---|---|---|
@supabase/middleware |
a built-in | src/middleware/README.md — layout, then the three subpath-wiring files |
| anything else | a standalone package | docs/authoring-guide.md — the full path, from defineMiddleware through publishing |
Both paths use the same defineMiddleware primitive; the difference is only whose package it lives in and whether a subpath export has to be wired up.
Read the guide before writing code, and follow its ## Rules section — eight MUST/NEVER items covering one-key-per-middleware, getEnv over process.env/Deno.env, declaring prerequisites in In, yielding at most once, and returning a Response to short-circuit rather than throwing. Its code blocks labeled with a path are complete files: write them to disk as given rather than adapting them from memory. Unlabeled blocks are fragments that elide with { ... }. Never write those verbatim.
Paths are repo-relative. When @supabase/middleware is installed as a dependency, prefix them with node_modules/@supabase/middleware/.