## TL;DR
aligns the remaining Phase 2 Edge Functions docs snippets with
`@supabase/server`
## Whats Fixed?
updated outdated imports and version references, and refreshed JSON
examples to use Response.json()
where it makes sense. left non-JSON responses as is where the
integration or format actually needs them
## Ref:
- towards COM-269
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Updated numerous Edge Function guides and examples to use modern
`npm:`/`jsr:` import specifiers instead of legacy Deno URL imports.
* Standardized success and error responses to return JSON consistently
(using `Response.json()` and equivalent helpers) and added/clarified
appropriate HTTP status codes.
* Improved example error payload shapes in several guides for clearer,
structured failures.
* **Chores**
* Refreshed version ranges in documentation and examples across SDKs and
client libraries.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What
Migrates the Edge Functions **documentation** from the legacy
`Deno.serve` + manual `createClient` pattern to the
[`@supabase/server`](https://github.com/supabase/server) `withSupabase`
wrapper. This is the part of
[COM-269](https://linear.app/supabase/issue/COM-269) that AI coding
assistants index, so it's split out to ship first; the standalone
`examples/` functions follow in a second PR.
## Canonical pattern
```ts
import { withSupabase } from 'npm:@supabase/server@1'
export default {
fetch: withSupabase({ auth: 'user' }, async (req, ctx) => {
const { data } = await ctx.supabase.from('countries').select('*')
return Response.json({ data })
}),
}
```
- `export default { fetch }` object shape (not `Deno.serve`, not a bare
default export), versioned `npm:@supabase/server@1`.
- `auth` mode picks the caller: `user` → `ctx.supabase` (RLS);
`secret`/`publishable`/`none` → set `verify_jwt = false`, `secret` uses
`ctx.supabaseAdmin`.
- `Response.json(...)` over `new Response(JSON.stringify(...))`.
## Changes
- **AI prompt** (`examples/prompts/edge-functions.md`) — rewritten to
lead with `withSupabase` as the default; `auth`-mode table;
`@supabase/server@1`. Highest AI-indexing impact.
- **connect-to-postgres** — "Using supabase-js" now uses `ctx.supabase`
(+ its CodeSample deps `postgres-on-the-edge`, `drizzle`).
- **Example pages** — semantic-search, push-notifications,
amazon-bedrock, cloudflare-turnstile, og-image, send-emails,
slack-bot-mention, auth-send-email-hook.
- **Guides** — ai-models, background-tasks, routing (+ `restful-tasks`
dep), kysely-postgres, sentry-monitoring, upstash-redis, elevenlabs ×2,
websockets, cors (reframed: CORS is automatic with `withSupabase`).
## Notable fixes
- **websockets**: the JWT-auth examples had a latent bug — handler
wasn't `async` and called `getClaims()` without the extracted token. Now
`await supabase.auth.getUser(jwt)`. (`withSupabase` can't authenticate
WebSocket clients since they can't send headers — noted in the page.)
- **restful-tasks**: fixed a broken `npm:supabase-js` import →
`npm:@supabase/supabase-js`.
## Follow-ups (not in this PR)
- The ~42 standalone `examples/` edge functions → second PR.
- A dedicated `withSupabase` intro page (today it's only documented
inside the auth-framed "Securing Edge Functions" page).
- `.claude/skills/supabase-server/SKILL.md` is stale (`allow:` vs
`auth:`).
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Updated Edge Function examples to the modern withSupabase + exported
fetch handler pattern across guides and examples.
* Standardized JSON response/error handling (uses built-in JSON helpers)
and preserved streaming/SSE behaviors where applicable.
* Clarified auth modes, context clients (user vs admin), and automatic
CORS handling; removed manual preflight boilerplate.
* Updated local serve/deploy instructions to include --no-verify-jwt for
relevant examples.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
Edge Function examples that use the new publishable/secret API keys read
them with a double lookup:
```ts
const SUPABASE_SECRET_KEYS = JSON.parse(Deno.env.get('SUPABASE_SECRET_KEYS')!)
const secretKey = Deno.env.get(SUPABASE_SECRET_KEYS['default']) // ❌ returns undefined
```
`SUPABASE_SECRET_KEYS` / `SUPABASE_PUBLISHABLE_KEYS` are a JSON object
that maps a key name to the **actual key value** (e.g.
`{"default":"sb_secret_..."}`), confirmed by:
- the self-hosted injection in `docker/docker-compose.yml`
(`SUPABASE_SECRET_KEYS: "{\"default\":\"${SUPABASE_SECRET_KEY:-}\"}"`)
- the `@supabase/server` SDK README
So `SUPABASE_SECRET_KEYS['default']` is already the key. Wrapping it in
another `Deno.env.get(...)` looks up an env var named `sb_secret_...`,
which doesn't exist, so the value is `undefined` and the examples fail
at runtime.
## Fix
Unwrap the outer `Deno.env.get(...)` so the key is read directly:
```ts
const SUPABASE_SECRET_KEYS = JSON.parse(Deno.env.get('SUPABASE_SECRET_KEYS')!)
const secretKey = SUPABASE_SECRET_KEYS['default'] // ✅
```
Applied across 23 files (example functions, the
`examples/prompts/edge-functions.md` codegen guidance, and two docs
guides). The correct `JSON.parse(Deno.env.get('SUPABASE_SECRET_KEYS')!)`
declaration line is untouched. The generated `apps/docs/examples/` copy
regenerates from `examples/` at build time.
## Notes
- Docs context:
[#46600](https://github.com/supabase/supabase/pull/46600), which
documents the same key model.
- Follow-up (not in this PR): a few examples send the secret key on the
`Authorization: Bearer` header, which the new keys reject. Worth a
separate audit.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Clarified examples and guides for correctly reading parsed Supabase
secret and publishable key maps.
* **Examples**
* Standardized credential usage across Edge Functions and samples so
Supabase clients consistently receive keys from the parsed key maps
rather than indirect lookups.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Chris Chinchilla <chris.ward@supabase.io>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Updated examples and guides to use Supabase publishable (client) keys
instead of anon keys for client-side usage across frameworks and
platforms.
* Renamed environment variable examples and .env templates to reflect
publishable key naming.
* Adjusted sample requests and client-init examples to send/use the
publishable key via the apikey header where applicable.
* Updated references from service_role to secret for server-side
credential guidance.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: fadymak <fady@fadymak.com>
## What
Updates all `setAll` cookie handler implementations across docs and
examples to accept the new `headers` second argument introduced in
`@supabase/ssr` v0.10.0
([supabase/ssr#176](https://github.com/supabase/ssr/pull/176)).
## Why
`@supabase/ssr` v0.10.0 introduced a breaking change: `setAll` now
receives a required second argument `headers: Record<string, string>`
alongside the cookies array. When a token refresh occurs, the library
passes cache headers (`Cache-Control`, `Expires`, `Pragma`) that must be
applied to the HTTP response to prevent CDN caching of auth responses.
Because TypeScript allows functions with fewer parameters to satisfy a
type expecting more, existing `setAll` implementations do not produce a
type error when the second argument is omitted. Users who copy an
outdated snippet will silently miss the CDN protection.
Root cause and context:
[supabase/supabase-js#1682](https://github.com/supabase/supabase-js/issues/1682)
## Changes
**Proxy/middleware contexts** (where token refreshes happen) now apply
the cache headers to their response:
- Next.js proxy files: `supabaseResponse.headers.set(key, value)`
- SvelteKit hooks: `event.setHeaders(headers)`
- Hono middleware: `c.header(key, value)`
- Pages Router (Express-style): `ctx.res.setHeader(key, value)`
- Remix/React Router loaders and actions: applied to response headers
(outer `headers` variable renamed to `responseHeaders` to avoid naming
conflict with the new param)
**Server Component and API route contexts** (no response object
available) accept `_headers` without applying them.
## Files updated
- `apps/docs/content/guides/auth/server-side/creating-a-client.mdx`
(inline Astro, Remix, React Router, Express snippets)
- `apps/docs/content/_partials/oauth_pkce_flow.mdx`
- `apps/docs/content/guides/auth/oauth-server/getting-started.mdx`
- `apps/docs/content/guides/auth/passwords.mdx`
-
`apps/docs/content/troubleshooting/how-to-migrate-from-supabase-auth-helpers-to-ssr-package-5NRunM.mdx`
- `examples/auth/nextjs/`, `examples/auth/nextjs-full/` (proxy + server)
- `examples/auth/sveltekit/`, `examples/auth/sveltekit-full/`
- `examples/auth/hono/`, `examples/auth/hono-full/`
- `examples/user-management/nextjs-user-management/` (proxy + server)
- `examples/user-management/sveltekit-user-management/`
- `examples/realtime/nextjs-authorization-demo/` (proxy + server)
- `examples/realtime/nextjs-auth-presence/` (pages router)
- `examples/prompts/nextjs-supabase-auth.md`
* Quickstart next 16 update
* Fix paths and env vars
* docs: refactor nextjs server-side auth to use Proxy instead of middleware
* docs: refactor nextjs server-side auth to match proxy
* docs: refactor nextjs example to match Proxy
* docs: refactor nextjs auth AI prompt to match Proxy
* docs: refactor nextjs sentry telemetry integration to match Proxy
* examples: update nextjs realtime example to match middleware
* docs: refactoring guides to use nextjs proxy
* examples: update nextjs-full example to match Next16 template
* example: update nextjs-user-management to match nextjs 16
* docs: refactoring nextjs user-management tutorial to use typescript only
* docs: refactoring nextjs quickstart, removing step 4
since this step is already included on `with-supabase` template, we can
just remove this redundant step
* docs: auth-helpers nextjs pages, Nextjs16 proxy disclaimer
* stamp: lint
* stamp: revert 'NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY'
* stamp: nextjs examples, revert to use cookie options
* fix(docs): typo
* docs: updating nextjs-auth troubleshoot guide to match proxy
* Update apps/docs/content/guides/getting-started/quickstarts/nextjs.mdx
* Revert auth-helpers changes
* Revert auth-helpers content
* Apply suggestions from code review
* Update apps/docs/content/troubleshooting/how-do-you-troubleshoot-nextjs---supabase-auth-issues-riMCZV.mdx
* Update apps/docs/content/troubleshooting/how-do-you-troubleshoot-nextjs---supabase-auth-issues-riMCZV.mdx
* Update apps/docs/content/troubleshooting/how-do-you-troubleshoot-nextjs---supabase-auth-issues-riMCZV.mdx
* Update apps/docs/content/troubleshooting/how-do-you-troubleshoot-nextjs---supabase-auth-issues-riMCZV.mdx
* Apply suggestions from code review
* Prettier
---------
Co-authored-by: kallebysantos <kalleby_santos@hotmail.com>
* remove glob from all examples
* Add declarative schema instructions
* run prettier
* update file extension for declarative-database-schema rule
* update the example prompts in the examples folder
* remove displaying heading for the AI prompts
* remove the prompt note for test
* revert the change for not displaying the heading for the menu
* Add back the title for each prompt
* allow putting frontmatter before heading
---------
Co-authored-by: Charis Lam <26616127+charislam@users.noreply.github.com>
* Update the instruction to add to project
* bringing Cursor at the front, because that is the most popular one of all
* Add sample description and globs for all sample prompt within the docs
* remove the cursor rule I created by mistake
* fix typo