--- id: usage-examples title: Usage examples --- Each example is a Fetch handler. Deno, Bun, and Supabase Edge Functions run the `export default { fetch }` shape as is. Cloudflare Workers also need the `nodejs_compat` flag or the `env` option, so `withSupabase` can read your project's URL and keys. On Node, use an adapter or the primitives with your framework. ### Protect an endpoint with a user JWT `withSupabase` wraps your handler. With `auth: 'user'`, it checks the caller's JWT before your handler runs. A request without valid credentials gets a JSON error response, and your handler never runs. `withSupabase` also answers every `OPTIONS` request with `204` and adds CORS headers to every response. Set `cors: 'disabled'` when your framework handles CORS. `ctx.supabase` is scoped to the caller, so Row Level Security policies apply. `ctx.supabaseAdmin` bypasses RLS. Use it only for work that needs full database access. ```ts import { withSupabase } from '@supabase/server' export default { fetch: withSupabase({ auth: 'user' }, async (_req, ctx) => { const { data } = await ctx.supabase.from('todos').select() return Response.json(data) }), } ``` ### Serve a public endpoint `auth: 'none'` lets every request through. `ctx.userClaims` is `null`, and `ctx.supabase` runs as an anonymous client. Supabase Edge Functions check for a valid JWT on every request by default. For a function that uses `auth: 'none'`, `auth: 'publishable'`, or `auth: 'secret'`, turn that check off in `supabase/config.toml`. The `auth` setting on `withSupabase` then decides who gets in. ```ts import { withSupabase } from '@supabase/server' export default { fetch: withSupabase({ auth: 'none' }, async () => { return Response.json({ status: 'ok', time: new Date().toISOString() }) }), } ``` ```toml supabase/config.toml [functions.my-function] verify_jwt = false ``` ### Build the context yourself `createSupabaseContext` runs the same auth checks as `withSupabase` but returns `{ data, error }` instead of a response. Use it inside a framework route handler, or anywhere you want to shape the error response yourself. On success, `data` is the same `SupabaseContext` that `withSupabase` passes to your handler. On failure, `error.status` holds the HTTP status to send. `createSupabaseContext` does not handle CORS. ```ts import { createSupabaseContext } from '@supabase/server' export default { fetch: async (req: Request) => { const { data: ctx, error } = await createSupabaseContext(req, { auth: 'user' }) if (error) { return Response.json(error.toJSON(), { status: error.status }) } const { data } = await ctx.supabase.from('todos').select() return Response.json(data) }, } ```