Auth modes, CORS, and environment overrides. See WithSupabaseConfig.
Receives the Request and a fully-initialized SupabaseContext.
A fetch handler. The optional second parameter is the host's
platform argument (a Workers env, a Deno ServeHandlerInfo) — when the
runtime supplies one, it is captured as the platform env behind
@supabase/middleware's getEnv for any composed middleware. Nested under
another middleware, it is that middleware's accumulated context instead,
which is reused rather than reseeded. At the entry point the request body
is buffered, so a nested middleware and the handler can both read it.
Type note. Base carries an upstream middleware's contributions into the
handler's ctx: with satisfies FetchHandler on the outermost call,
withOAuthProtectedResource(withSupabase(config, handler)) types
ctx.oauthProtectedResource with no annotation. The anchor is the same one
the engine already asks of nested stacks (it also gates collision detection
there): Base flows from the contextual return type, and without the anchor
the outer call resolves before it can push, so Base stays the empty
upstream and upstream keys are absent from ctx. Supplying Database explicitly
(withSupabase<Db>(...)) also defaults every later type parameter, Base
included; in that case annotate both (withSupabase<Db, UpstreamCtx>(...))
or read the upstream key through a cast.
AlphaAlpha. Config-only call: returns an entry for a pipeline array, so
withSupabase composes by position with any other middleware. Entries
placed before it run ahead of the auth gate and may answer unauthenticated
requests; entries placed after it receive the full SupabaseContext
and may declare prerequisites on its keys.
The composable surface tracks @supabase/middleware 0.x — entry shapes and
context keys may change between 0.x releases. The handler-form overload is
stable.
import { pipeline } from '@supabase/middleware'
import { withOAuthProtectedResource, withSupabase } from '@supabase/server'
import { withPostgresClient } from '@supabase/server/middleware/postgres'
export default {
fetch: pipeline(
[withOAuthProtectedResource(), withSupabase({ auth: 'user' }), withPostgresClient()],
async (_req, ctx) => {
const rows = await ctx.postgres.query`select id, body from notes`
return Response.json(rows)
},
),
}
Wraps a request handler with Supabase auth, client creation, and CORS handling.
Built for the Web API
Request/Responsestandard that all modern runtimes implement natively. Handles CORS preflight, credential verification, context creation, and error responses. Your handler only runs on successful auth.