Files
supabase/examples/edge-functions
Tomás PozoandChris Chinchilla e3be344f5c fix(examples): read new API keys directly from parsed SUPABASE_SECRET_KEYS (#46604)
## 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>
2026-06-03 11:05:20 -05:00
..

Supabase Edge Function Examples

What are Supabase Edge Functions?

Supabase Edge Functions are written in TypeScript, run via Deno, and deployed with the Supabase CLI. Please download the latest version of the Supabase CLI, or upgrade it if you have it already installed.

Example Functions

We're constantly adding new Function Examples, check our docs for a complete list!

Develop locally

  • Run supabase start (make sure your Docker daemon is running.)
  • Run cp ./supabase/.env.local.example ./supabase/.env.local to create your local .env file.
  • Set the required variables for the corresponding edge functions in the .env.local file.
  • Run supabase functions serve --env-file ./supabase/.env.local --no-verify-jwt
  • Run the CURL command in the example function, or use the invoke method on the Supabase client or use the test client app.

Test Client

This example includes a create-react-app in the ./app/ directory which you can use as a sort of postman to make test requests both locally and to your deployed functions.

Test locally

  • cd app
  • npm install
  • npm start

Note: when testing locally, the select dropdown doesn't have any effect, and invoke simply calls whatever function is currently served by the CLI.

Deploy

  • Generate access token and log in to CLI

  • Link your project

    • Within your project root run supabase link --project-ref your-project-ref
  • Set up your secrets

    • Run supabase secrets set --env-file ./supabase/.env.local to set the environment variables.

    (This is assuming your local and production secrets are the same. The recommended way is to create a separate .env file for storing production secrets, and then use it to set the environment variables while deploying.)

    • You can run supabase secrets list to check that it worked and also to see what other env vars are set by default.
  • Deploy the function

    • Within your project root run supabase functions deploy your-function-name
  • In your ./app/.env file remove the SUPA_FUNCTION_LOCALHOST variable and restart your Expo app.

Test deployed functions

This example includes a create-react-app in the ./app/ directory which you can use as a sort of postman to make test requests both locally and to your deployed functions.

Deploy via GitHub Actions

This example includes a deploy GitHub Action that automatically deploys your Supabase Edge Functions when pushing to or merging into the main branch.

You can use the setup-cli GitHub Action to run Supabase CLI commands in your GitHub Actions, for example to deploy a Supabase Edge Function:

name: Deploy Function

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-latest

    env:
      SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
      PROJECT_ID: your-project-id

    steps:
      - uses: actions/checkout@v3

      - uses: supabase/setup-cli@v1
        with:
          version: latest

      - run: supabase functions deploy --project-ref $PROJECT_ID

Since Supabase CLI v1.62.0 you can deploy all functions with a single command.

Individual function configuration like JWT verification and import map location can be set via the config.toml file.

[functions.hello-world]
verify_jwt = false

👁⚡️👁

\o/ That's it, you can now invoke your Supabase Function via the supabase-js and supabase-dart client libraries. (More client libraries coming soon. Check the supabase-community org for details).

For more info on Supabase Functions, check out the docs and the examples.