Merge remote-tracking branch 'origin/master' into feature/assistant-eval-support-cases

This commit is contained in:
Barco Fourie committed 2026-10-15 11:35:22 +02:00
commit f1b793bab2
1941 files changed
+34761 -12577

No files matched your search

@@ -53,8 +53,7 @@ flowchart TB
| -------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `app/` | Next.js App Router — thin route files that delegate to feature modules | Slug-based catch-alls per section, e.g. `guides/auth/[[...slug]]/page.tsx` |
| `apps/docs/content/guides/` | Source MDX for `/docs/guides/...` pages | One file per page; `_partials/` for shared blocks |
| `apps/docs/content/_partials/` | Reusable MDX snippets included via `<$Partial path="..." />` | Recursion supported |
| `apps/docs/content/troubleshooting/` | Troubleshooting articles | Some synced from GitHub issues via `Troubleshooting.script.mjs` |
| `apps/docs/content/_partials/` | Reusable MDX snippets included via `<$Partial path="..." />` | Recursion supported | |
| `apps/docs/components/` | React components used inside MDX | One folder per component or component family |
| `apps/docs/data/` | Typed data modules consumed by components | `.data.ts` suffix; lookup helpers live in `.utils.ts`, not here |
| `apps/docs/lib/` | Pure library code shared across pipelines | Schemas (zod), helpers (`.utils.ts`), tests |
@@ -218,14 +217,10 @@ Wraps the app with:
- `DocsCommandProvider` / `DocsCommandMenu`
- `SiteLayout` from `layouts/`
## Troubleshooting page subtree
- `features/docs/Troubleshooting.page.tsx` — entry-level page renderer.
- `features/docs/Troubleshooting.utils.ts` — TS utils.
- `features/docs/Troubleshooting.utils.common.mjs` — `.mjs` because it's
consumed by both the Next.js build _and_ a Node sync script with import
resolution quirks. **Don't convert to `.ts`** without checking the sync
script.
- `features/docs/Troubleshooting.utils.common.mjs` — `.mjs`, shared between
the Next.js build and other scripts that read troubleshooting entries
(e.g. search embeddings generation).
- Topics enum in `TroubleshootingSchema` (the `topics` field) is the source
of truth for product tag values.
@@ -140,8 +140,6 @@ pnpm dev # http://localhost:3001/docs
```
- **`predev`** runs GraphQL and reference codegen plus example copy.
- A concurrent watcher syncs troubleshooting content
(`dev:watch:troubleshooting`).
- Community contributors: set `NEXT_PUBLIC_IS_PLATFORM=false` in `.env`.
- Supabase employees: `pnpm run dev:secrets:pull` for internal env vars
(AWS profile + `scripts/getSecrets.js`).
@@ -76,15 +76,6 @@ Specific traps to watch for. One-liner per item.
URLs are passed through. Use it consistently in markdown output to avoid
broken links.
## Troubleshooting subtree
- `Troubleshooting.utils.common.mjs` is `.mjs` because the troubleshooting
sync script can't resolve `.ts` imports cleanly. Don't convert it.
- Rebasing can resurrect a **stale** version of this file when you reset
unrelated changes — verify against current `master` after
`git checkout master -- <path>`.
- The `topics` enum in `TroubleshootingSchema` is hand-maintained. Adding a
new product means updating that enum.
## Build / CI
+2
View File
@@ -11,6 +11,8 @@
/apps/docs/ @supabase/docs
/apps/kb/ @supabase/docs
/apps/www/ @supabase/marketing
/apps/www/public/images/blog @supabase/marketing
/apps/www/lib/redirects.js
@@ -1,59 +0,0 @@
name: '[Docs] Sync troubleshooting guides to GitHub Discussions'
on:
push:
branches:
- master
paths:
- 'apps/docs/content/troubleshooting/**'
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
update-troubleshooting:
runs-on: blacksmith-4vcpu-ubuntu-2404
env:
DOCS_GITHUB_APP_ID: ${{ secrets.SEARCH_GITHUB_APP_ID }}
DOCS_GITHUB_APP_INSTALLATION_ID: ${{ secrets.SEARCH_GITHUB_APP_INSTALLATION_ID }}
DOCS_GITHUB_APP_PRIVATE_KEY: ${{ secrets.SEARCH_GITHUB_APP_PRIVATE_KEY }}
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.SEARCH_SUPABASE_URL }}
SUPABASE_SECRET_KEY: ${{ secrets.SEARCH_SUPABASE_SERVICE_ROLE_KEY }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
sparse-checkout: |
apps/docs
patches
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
name: Install pnpm
with:
run_install: false
- name: Use Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run Troubleshooting script
run: pnpm run --filter docs troubleshooting:sync
- name: Create Pull Request
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5
with:
commit-message: '[bot] sync troubleshooting guides to db'
title: '[bot] sync troubleshooting guides to db'
author: 'github-docs-sync-bot <github-docs-sync-bot@supabase.com>'
branch: 'bot/docs-sync-troubleshooting'
branch-suffix: 'random'
labels: 'documentation'
@@ -0,0 +1,56 @@
name: 'KB Troubleshooting Sync'
on:
push:
branches:
- master
workflow_dispatch:
permissions:
contents: read
jobs:
sync:
runs-on: blacksmith-4vcpu-ubuntu-2404
env:
KB_GITHUB_APP_ID: ${{ secrets.KB_GITHUB_APP_ID }}
KB_GITHUB_APP_INSTALLATION_ID: ${{ secrets.KB_GITHUB_APP_INSTALLATION_ID }}
KB_GITHUB_APP_PRIVATE_KEY: ${{ secrets.KB_GITHUB_APP_PRIVATE_KEY }}
SUPABASE_URL: ${{ secrets.SEARCH_SUPABASE_URL }}
SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SEARCH_SUPABASE_SERVICE_ROLE_KEY }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
sparse-checkout: |
apps/kb
packages
patches
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
name: Install pnpm
with:
run_install: false
- name: Use Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Backfill legacy troubleshooting slugs
run: pnpm run --filter kb sync:legacy-slugs
- name: Fetch federated troubleshooting content
run: pnpm run --filter kb fetch:federated-content
- name: Sync new troubleshooting entries
run: pnpm run --filter kb sync:troubleshooting-entries
- name: Sync troubleshooting entry updates
run: pnpm run --filter kb sync:troubleshooting-updates
Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

+4 -1
View File
@@ -11,11 +11,14 @@ import { inter, manrope, sourceCodePro } from '@/lib/fonts'
const className = `${inter.variable} ${manrope.variable} ${sourceCodePro.variable}`
const FAVICON_ROUTE = process.env.NODE_ENV === 'development' ? '/favicon/local' : '/favicon'
export const metadata: Metadata = {
applicationName: 'Supabase Design System',
title: 'Supabase Design System',
description: 'Design resources for building consistent user experiences at Supabase.',
icons: genFaviconData(BASE_PATH),
icons: genFaviconData(BASE_PATH, FAVICON_ROUTE),
manifest: `${BASE_PATH}${FAVICON_ROUTE}/manifest.json`,
}
export const viewport: Viewport = {
@@ -26,11 +26,11 @@ export function ComponentExample({
}: ComponentExampleProps) {
const [Example, Code, ...Children] = React.Children.toArray(children) as React.ReactElement<{
children: React.ReactNode
'data-rehype-pretty-code-fragment'?: unknown
'data-rehype-pretty-code-figure'?: unknown
}>[]
const codeString = React.useMemo(() => {
if (typeof Code?.props['data-rehype-pretty-code-fragment'] !== 'undefined') {
if (typeof Code?.props['data-rehype-pretty-code-figure'] !== 'undefined') {
const [, Button] = React.Children.toArray(Code.props.children) as React.ReactElement<{
value?: string
__rawString__?: string
+14 -1
View File
@@ -310,8 +310,21 @@ const SourcePanel = forwardRef<HTMLDivElement, React.HTMLProps<HTMLDivElement> &
}
}
const hasSource = Boolean(
doc.source?.radix ||
doc.source?.shadcn ||
doc.source?.vaul ||
doc.source?.inputOtp ||
doc.source?.reactAccessibleTreeview ||
doc.source?.recharts
)
if (!hasSource) {
return null
}
return (
<div className="flex flex-col -space-y-px">
<div className="mb-6 flex flex-col -space-y-px">
<RadixPanel />
<ShadcnPanel />
<VaulPanel />
-5
View File
@@ -127,11 +127,6 @@ export const docsConfig: DocsConfig = {
href: '/docs/fragments/admonition',
items: [],
},
{
title: 'Collapsible Alert',
href: '/docs/fragments/collapsible-alert',
items: [],
},
{
title: 'Collapsible Card Section',
href: '/docs/fragments/collapsible-card-section',
@@ -11,7 +11,7 @@ Alert is the low-level shadcn primitive that forms the foundation for [Admonitio
Examples where Alert may be appropriate include bespoke icons, custom internal layouts, or wrapper components that need direct access to `alertVariants`.
Use [Collapsible Alert](../fragments/collapsible-alert) when a callout also needs expandable detail. Use [Collapsible](./collapsible) only for generic disclosure behaviour that is not itself an alert.
Compose Alert with [Collapsible](./collapsible) when a callout needs expandable detail. Use [DialogDisclosure](./dialog#optional-details) for optional details in a dialog.
<ComponentPreview name="alert-demo" peekCode wide />
@@ -6,7 +6,7 @@ component: true
Collapsible is a low-level primitive for revealing and hiding related content. Use it when a component needs custom trigger or content composition.
Use Collapsible for generic disclosure behaviour: rows, sections, menus, tool details, and custom layouts. Use [Collapsible Alert](../fragments/collapsible-alert) instead when the disclosure is an alert-styled callout that should keep standard alert padding, variants, trigger styling, and toggle treatment.
Use Collapsible for generic disclosure behavior: rows, sections, menus, tool details, and custom layouts. Use [DialogDisclosure](./dialog#optional-details) for optional details in a dialog.
<ComponentPreview name="collapsible-demo" peekCode wide />
@@ -65,6 +65,14 @@ import {
## Examples
### Optional details
Use `DialogDisclosure` to reveal optional help or context inside a dialog. Put the trigger in the dialog body above the footer, and add a section separator when the disclosure follows other content. Keep the primary action visible while the details are open or closed.
`Collapsible` provides the open and closed state. `DialogDisclosure` adds the trigger and content presentation used in dialogs. Use `Accordion` when several related sections each need a heading and expandable content.
<ComponentPreview name="dialog-disclosure-demo" peekCode wide />
### Custom close button
<ComponentPreview name="dialog-close-button" />
@@ -15,7 +15,7 @@ Admonition provides the standard product callout pattern for situations that req
Use Admonition instead of the low-level [Alert](../components/alert) primitive unless you specifically need custom composition. If in doubt, stick with Admonition.
Use [Collapsible Alert](./collapsible-alert) when the callout needs to remain visible while optional detail can be expanded. Use [Collapsible](../components/collapsible) for generic disclosure behaviour that is not itself a callout.
Use [Collapsible](../components/collapsible) for custom expandable content. Use [DialogDisclosure](../components/dialog#optional-details) for optional details in a dialog.
Use `title` for the heading slot when the callout needs its own heading. `title` is optional: short callouts may use `description` without a title when nearby content already provides enough context.
@@ -1,43 +0,0 @@
---
title: Collapsible Alert
description: An alert-styled block with a collapsible content section, toggled by an icon button.
fragment: true
---
Collapsible Alert combines an Alert-style container with a collapsible content section. Use it when the callout itself needs to stay visible while optional detail can be expanded.
Use Collapsible Alert when the disclosure is itself a callout. It owns the alert styling, padding, trigger treatment, and toggle button. Use [Collapsible](../components/collapsible) instead when you only need generic reveal and hide behaviour and the surrounding layout is not an alert.
For non-expandable product callouts, use [Admonition](./admonition). Use the low-level [Alert](../components/alert) primitive only when a wrapper or bespoke composition needs direct control over the alert structure.
<ComponentPreview name="collapsible-alert-demo" peekCode wide />
## Usage
```tsx
import { CollapsibleAlert } from 'ui-patterns/collapsible-alert'
```
```tsx
<CollapsibleAlert trigger="Need help?">
<p>Content revealed when expanded.</p>
</CollapsibleAlert>
```
### Default open
```tsx
<CollapsibleAlert trigger="Details" defaultOpen>
<p>This section is expanded by default.</p>
</CollapsibleAlert>
```
### Variants
Supports the same `variant` prop as Alert: `default`, `destructive`, and `warning`.
```tsx
<CollapsibleAlert trigger="Warning" variant="warning">
<p>Something needs attention.</p>
</CollapsibleAlert>
```
+2 -3
View File
@@ -40,7 +40,7 @@
"react-wrap-balancer": "^1.1.0",
"recharts": "catalog:",
"rehype-autolink-headings": "^7.1.0",
"rehype-pretty-code": "^0.9.0",
"rehype-pretty-code": "catalog:",
"rehype-slug": "^6.0.0",
"remark": "^14.0.3",
"remark-code-import": "^1.2.0",
@@ -54,7 +54,6 @@
"zod": "catalog:"
},
"devDependencies": {
"@shikijs/compat": "^1.1.7",
"@types/lodash.template": "4.5.0",
"@types/react": "catalog:",
"@types/react-dom": "catalog:",
@@ -64,7 +63,7 @@
"npm-run-all": "^4.1.5",
"postcss": "catalog:",
"rimraf": "^4.1.3",
"shiki": "^1.1.7",
"shiki": "catalog:",
"tailwindcss": "catalog:",
"tsconfig": "workspace:*",
"tsx": "catalog:",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 584 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 765 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 971 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 794 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 854 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 971 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1007 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig><msapplication><tile><square70x70logo src="/favicon/ms-icon-70x70.png"/><square150x150logo src="/favicon/ms-icon-150x150.png"/><square310x310logo src="/favicon/ms-icon-310x310.png"/><TileColor>#ffffff</TileColor></tile></msapplication></browserconfig>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 558 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

@@ -0,0 +1,22 @@
{
"name": "Supabase Design System",
"short_name": "Supabase Design System",
"description": "Design resources for building consistent user experiences at Supabase.",
"display": "standalone",
"theme_color": "#1C1C1C",
"background_color": "#1C1C1C",
"icons": [
{
"src": "android-icon-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "android-icon-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
}
]
}
@@ -7,40 +7,16 @@
"background_color": "#1C1C1C",
"icons": [
{
"src": "/favicon/android-icon-36x36.png",
"sizes": "36x36",
"type": "image/png",
"density": "0.75"
},
{
"src": "/favicon/android-icon-48x48.png",
"sizes": "48x48",
"type": "image/png",
"density": "1.0"
},
{
"src": "/favicon/android-icon-72x72.png",
"sizes": "72x72",
"type": "image/png",
"density": "1.5"
},
{
"src": "/favicon/android-icon-96x96.png",
"sizes": "96x96",
"type": "image/png",
"density": "2.0"
},
{
"src": "/favicon/android-icon-144x144.png",
"sizes": "144x144",
"type": "image/png",
"density": "3.0"
},
{
"src": "/favicon/android-icon-192x192.png",
"src": "android-icon-192x192.png",
"sizes": "192x192",
"type": "image/png",
"density": "4.0"
"purpose": "any"
},
{
"src": "android-icon-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
}
]
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 955 B

@@ -1,11 +0,0 @@
import { CollapsibleAlert } from 'ui-patterns/collapsible-alert'
export default function CollapsibleAlertDemo() {
return (
<CollapsibleAlert trigger="Need help?">
<p className="text-sm text-foreground-light">
Try a different browser or disable extensions that block network requests.
</p>
</CollapsibleAlert>
)
}
@@ -0,0 +1,64 @@
import {
Button,
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogSection,
DialogSectionSeparator,
DialogTitle,
DialogTrigger,
} from 'ui'
import {
DialogDisclosure,
DialogDisclosureContent,
DialogDisclosureTrigger,
} from 'ui-patterns/DialogDisclosure'
export default function DialogDisclosureDemo() {
return (
<Dialog>
<DialogTrigger asChild>
<Button>Export results</Button>
</DialogTrigger>
<DialogContent size="small">
<DialogHeader>
<DialogTitle>Export results</DialogTitle>
</DialogHeader>
<DialogSectionSeparator />
<DialogSection>
<p className="text-sm text-foreground-light">
All 250 rows will be downloaded as a CSV file.
</p>
</DialogSection>
<DialogSectionSeparator />
<DialogDisclosure>
<DialogDisclosureTrigger className="px-4 py-4 md:px-5">
What’s included
</DialogDisclosureTrigger>
<DialogDisclosureContent>
<DialogSection className="pt-1 text-sm text-foreground-light space-y-3">
<p>The file includes column names in the first row, followed by the query results.</p>
<ul className="list-disc pl-5 space-y-1">
<li>Columns keep the same order as the results table.</li>
<li>Empty fields represent null values.</li>
<li>Values containing commas or line breaks are enclosed in double quotes.</li>
</ul>
<p>Open the file in a spreadsheet or import it into another tool.</p>
</DialogSection>
</DialogDisclosureContent>
</DialogDisclosure>
<DialogFooter>
<DialogClose asChild>
<Button>Cancel</Button>
</DialogClose>
<DialogClose asChild>
<Button variant="primary">Download CSV</Button>
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
)
}
+6 -6
View File
@@ -67,12 +67,6 @@ export const examples: Registry = [
registryDependencies: ['alert'],
files: ['example/alert-demo.tsx'],
},
{
name: 'collapsible-alert-demo',
type: 'components:example',
registryDependencies: ['collapsible-alert'],
files: ['example/collapsible-alert-demo.tsx'],
},
{
name: 'collapsible-card-section-demo',
type: 'components:example',
@@ -551,6 +545,12 @@ export const examples: Registry = [
registryDependencies: ['dialog'],
files: ['example/dialog-demo.tsx'],
},
{
name: 'dialog-disclosure-demo',
type: 'components:example',
registryDependencies: ['dialog', 'collapsible', 'button'],
files: ['example/dialog-disclosure-demo.tsx'],
},
{
name: 'dialog-close-button',
type: 'components:example',
+12 -11
View File
@@ -16,25 +16,25 @@
display: block;
}
[data-rehype-pretty-code-fragment] {
[data-rehype-pretty-code-figure] {
@apply relative;
}
[data-rehype-pretty-code-fragment] code {
[data-rehype-pretty-code-figure] code {
@apply grid min-w-full break-words rounded-none border-0 bg-transparent p-0;
counter-reset: line;
box-decoration-break: clone;
}
[data-rehype-pretty-code-fragment] .line {
[data-rehype-pretty-code-figure] [data-line] {
@apply px-4 min-h-[1rem] py-0.5 w-full inline-block;
}
[data-rehype-pretty-code-fragment] [data-line-numbers] .line {
[data-rehype-pretty-code-figure] [data-line-numbers] [data-line] {
@apply px-2;
}
[data-rehype-pretty-code-fragment] [data-line-numbers] > .line::before {
[data-rehype-pretty-code-figure] [data-line-numbers] > [data-line]::before {
@apply text-foreground-muted text-xs;
counter-increment: line;
content: counter(line);
@@ -44,23 +44,24 @@
text-align: right;
}
[data-rehype-pretty-code-fragment] .line--highlighted {
[data-rehype-pretty-code-figure] .line--highlighted {
@apply relative bg-surface-200 dark:bg-surface-100;
}
[data-rehype-pretty-code-fragment] .line--highlighted {
[data-rehype-pretty-code-figure] .line--highlighted {
@apply border-foreground-muted border-l-2;
}
[data-rehype-pretty-code-fragment] .line-highlighted span {
[data-rehype-pretty-code-figure] .line-highlighted span {
@apply relative;
}
[data-rehype-pretty-code-fragment] .word--highlighted {
@apply rounded-md bg-zinc-700/50 border-zinc-700/70 p-1;
/* reset <mark> default text color */
[data-rehype-pretty-code-figure] .word--highlighted {
@apply rounded-md bg-zinc-700/50 border-zinc-700/70 p-1 text-inherit;
}
.dark [data-rehype-pretty-code-fragment] .word--highlighted {
.dark [data-rehype-pretty-code-figure] .word--highlighted {
@apply bg-zinc-900;
}
+1 -1
View File
@@ -4,7 +4,7 @@
"tasks": {
"build": {
"dependsOn": ["^build"],
"env": ["NEXT_PUBLIC_BASE_PATH", "NEXT_PUBLIC_APP_URL"],
"env": ["NODE_ENV", "NEXT_PUBLIC_BASE_PATH", "NEXT_PUBLIC_APP_URL"],
"outputs": [".next/**", "!.next/cache/**", "!.next/dev/**/*", ".velite/**"],
},
},
+14 -19
View File
@@ -1,7 +1,6 @@
/* eslint-disable turbo/no-undeclared-env-vars */
import { mkdir, rename, writeFile } from 'node:fs/promises'
import { mkdir, readFile, rename, writeFile } from 'node:fs/promises'
import path from 'path'
import { getHighlighter, loadTheme } from '@shikijs/compat'
import rehypeAutolinkHeadings from 'rehype-autolink-headings'
import rehypePrettyCode from 'rehype-pretty-code'
import rehypeSlug from 'rehype-slug'
@@ -14,6 +13,10 @@ import { rehypeComponent } from './lib/rehype-component'
const CODE_OUTPUT_DIR = '.velite/codes'
const codeTheme = JSON.parse(
await readFile(path.join(process.cwd(), 'lib/themes/supabase-2.json'), 'utf8')
)
function toCodeId(slugAsParams) {
if (!slugAsParams) return 'index'
return Buffer.from(slugAsParams, 'utf8').toString('base64url')
@@ -118,18 +121,9 @@ export default defineConfig({
[
rehypePrettyCode,
{
// Memoized so the (expensive) theme parse + oniguruma WASM init runs once
// for the whole build, instead of once per file — velite compiles every
// file concurrently, so without this every doc pays that cost redundantly.
getHighlighter: (() => {
let highlighterPromise
return () => {
highlighterPromise ??= loadTheme(
path.join(process.cwd(), '/lib/themes/supabase-2.json')
).then((theme) => getHighlighter({ theme }))
return highlighterPromise
}
})(),
// plugin shares one cached highlighter per theme, lazy language loading needs shiki >= 4.5 (shikijs/shiki#1318)
theme: codeTheme,
keepBackground: false,
onVisitLine(node) {
// Prevent lines from collapsing in `display: grid` mode, and allow empty
// lines to be copy/pasted
@@ -138,17 +132,18 @@ export default defineConfig({
}
},
onVisitHighlightedLine(node) {
node.properties.className.push('line--highlighted')
// the plugin strips the `line` class first, leaving className undefined
node.properties.className = [...(node.properties.className ?? []), 'line--highlighted']
},
onVisitHighlightedWord(node) {
onVisitHighlightedChars(node) {
node.properties.className = ['word--highlighted']
},
},
],
() => (tree) => {
visit(tree, (node) => {
if (node?.type === 'element' && node?.tagName === 'div') {
if (!('data-rehype-pretty-code-fragment' in node.properties)) {
if (node?.type === 'element' && node?.tagName === 'figure') {
if (!('data-rehype-pretty-code-figure' in node.properties)) {
return
}
@@ -157,7 +152,7 @@ export default defineConfig({
return
}
preElement.properties['__withMeta__'] = node.children.at(0).tagName === 'div'
preElement.properties['__withMeta__'] = node.children.at(0).tagName === 'figcaption'
preElement.properties['__rawString__'] = node.__rawString__
if (node.__src__) {
+4 -1
View File
@@ -19,13 +19,16 @@ const { metadataApplicationName, metadataTitle } = getCustomContent([
'metadata:title',
])
const FAVICON_ROUTE = process.env.NODE_ENV === 'development' ? '/favicon/local' : '/favicon'
const metadata: Metadata = {
applicationName: metadataApplicationName,
title: metadataTitle,
description:
'Supabase is the Postgres development platform providing all the backend features you need to build a product.',
metadataBase: new URL('https://supabase.com'),
icons: genFaviconData(BASE_PATH),
icons: genFaviconData(BASE_PATH, FAVICON_ROUTE),
manifest: `${BASE_PATH}${FAVICON_ROUTE}/manifest.json`,
robots: {
index: IS_PRODUCTION,
follow: IS_PRODUCTION,
+1 -1
View File
@@ -1,6 +1,6 @@
'use client'
import { domAnimation, LazyMotion, m } from 'framer-motion'
import { domAnimation, LazyMotion, m } from 'motion/react'
import React, { type ComponentPropsWithoutRef } from 'react'
const DocsCoverLogo = ({ className, ...props }: ComponentPropsWithoutRef<'div'>) => {
@@ -62,7 +62,7 @@ const navCommands = [
{
id: 'nav-local-cli',
name: 'Go to Local Dev / CLI',
route: '/guides/cli',
route: '/guides/local-development',
icon: () => <ArrowRight />,
},
{
@@ -1,7 +1,7 @@
import { getCustomContent } from '~/lib/custom-content/getCustomContent'
import { useIsLoggedIn, useIsUserLoading } from 'common'
import { AnimatePresence, domAnimation, LazyMotion, m } from 'framer-motion'
import { X } from 'lucide-react'
import { AnimatePresence, domAnimation, LazyMotion, m } from 'motion/react'
import Image from 'next/image'
import Link from 'next/link'
import { usePathname } from 'next/navigation'
@@ -259,7 +259,6 @@ export const GLOBAL_MENU_ITEMS: GlobalMenuItems = [
icon: 'reference-csharp',
href: '/reference/csharp' as `/${string}`,
level: 'reference_csharp',
community: true,
enabled: sdkCsharpEnabled,
},
{
@@ -541,18 +540,6 @@ export const gettingstarted: NavMenuConstant = {
],
}
export const cli = {
title: 'CLI',
items: [
{ name: 'Overview', url: '/guides/cli' },
{ name: 'Managing Environments', url: '/guides/cli/managing-environments' },
{
name: 'Using environment variables in config.toml',
url: '/guides/cli/using-environment-variables-in-config',
},
],
}
export const NativeMobileLoginItems = [
{
name: 'Apple',
@@ -884,6 +871,7 @@ export const auth: NavMenuConstant = {
{ name: 'Auth0', url: '/guides/auth/third-party/auth0' },
{ name: 'AWS Cognito (Amplify)', url: '/guides/auth/third-party/aws-cognito' },
{ name: 'WorkOS', url: '/guides/auth/third-party/workos' },
{ name: 'Custom OIDC', url: '/guides/auth/third-party/custom-oidc' },
],
},
{
@@ -2693,6 +2681,7 @@ export const security: NavMenuConstant = {
url: undefined,
items: [
{ name: 'Platform configuration', url: '/guides/security/platform-security' },
{ name: 'TLS for project APIs', url: '/guides/security/tls' },
{ name: 'Product configuration', url: '/guides/security/product-security' },
{ name: 'Security testing', url: '/guides/security/security-testing' },
{ name: 'Platform Audit Logs', url: '/guides/security/platform-audit-logs' },
@@ -3536,7 +3525,7 @@ export const reference_csharp_v0 = {
parent: '/reference',
pkg: {
name: 'supabase',
repo: 'https://github.com/supabase-community/supabase-csharp',
repo: 'https://github.com/supabase/supabase-csharp',
},
}
@@ -3547,7 +3536,7 @@ export const reference_csharp_v1 = {
parent: '/reference',
pkg: {
name: 'supabase',
repo: 'https://github.com/supabase-community/supabase-csharp',
repo: 'https://github.com/supabase/supabase-csharp',
},
}
@@ -3558,7 +3547,7 @@ export const reference_csharp_v8 = {
parent: '/reference',
pkg: {
name: 'supabase',
repo: 'https://github.com/supabase-community/supabase-csharp',
repo: 'https://github.com/supabase/supabase-csharp',
},
}
@@ -13,6 +13,7 @@ import React, { useEffect, useRef } from 'react'
import MenuIconPicker from './MenuIconPicker'
type NavAccordionItem = {
name?: string
url?: string
enabled?: boolean
items?: NavAccordionItem[]
@@ -31,6 +32,15 @@ function isRenderable(item: NavAccordionItem): boolean {
return item.items?.some(isRenderable) ?? false
}
function groupLinks(item: NavAccordionItem): Array<{ name: string; url: string }> {
return (item.items ?? [])
.filter((child) => isRenderable(child))
.flatMap((child) => [
...(child.url && child.name ? [{ name: child.name, url: child.url }] : []),
...groupLinks(child),
])
}
const HeaderLink = React.memo(function HeaderLink(props: {
title: string
id: string
@@ -164,6 +174,13 @@ const ContentAccordionLink = React.memo(function ContentAccordionLink(props: any
</NavSectionList>
</NavSectionContent>
</Accordion.Content>
<ul hidden>
{groupLinks(props.subItem).map((child) => (
<li key={`${child.name}-${child.url}`}>
<Link href={child.url}>{child.name}</Link>
</li>
))}
</ul>
</Accordion.Item>
</Accordion.Root>
) : (
+31 -24
View File
@@ -4,20 +4,39 @@ Rate limits are applied to prevent abuse and ensure fair usage of the Management
### Standard rate limit
| Limit | Duration | Scope |
| ------------ | -------- | ---------------------------------- |
| 120 requests | 1 minute | Per user, per project/organization |
| Limit | Duration | Scope |
| ------------ | -------- | --------------------------------------------------- |
| 120 requests | 1 minute | Per user, per project or organization, per endpoint |
When you exceed this rate limit, all subsequent API calls will return a `429 Too Many Requests` response for the remainder of the minute. Once the time window expires, your request quota resets and you can make requests again.
When you exceed this rate limit, all further API calls return a `429 Too Many Requests` response for the remainder of the minute. Once the time window expires, your request quota resets and you can make requests again.
### Rate limit scope
Rate limits are applied with per-user + per-scope isolation:
Rate limits are applied with per-user, per-scope, per-endpoint isolation:
- **Project scope**: Rate limits apply independently to each project. Requests to one project do not count toward the limit of another project.
- **Organization scope**: Rate limits apply independently to each organization. Requests to one organization do not count toward the limit of another organization.
- **Project scope**: rate limits apply independently to each project.
- **Organization scope**: rate limits apply independently to each organization.
- **User scope**: requests that don't include a project or organization, such as `GET /v1/projects` and `GET /v1/organizations`, are counted against the user.
- **Endpoint**: within each scope, every endpoint has its own limit.
This means you can make 120 requests to Project A and 120 requests to Project B within the same minute without hitting rate limits, as they are tracked separately.
For example, you can make 120 requests to Project A and 120 requests to Project B within the same minute, as they are tracked separately. Within one organization, calling `GET /v1/organizations/{slug}/members` 120 times doesn't affect calls to `GET /v1/organizations/{slug}` or `POST /v1/projects` for that organization.
`POST /v1/projects` is organization-scoped, using the `organization_slug` in the request body.
### How rate limits are tracked
Your requests are identified and tracked using one of the following identifiers, in this order of priority:
1. **OAuth App ID**: If your request is authenticated via an OAuth application
2. **User ID**: If your request is authenticated with a personal access token
3. **IP Address**: If your request is unauthenticated (extracted from request headers)
Each identifier is combined with the scope (project or organization) and the endpoint to create a unique tracking key. This ensures that rate limits are isolated per user and per scope, preventing one project or organization from affecting another.
### Who the limit applies to
- **Personal access tokens**: the limit applies to the user, so all tokens created by the same user share it.
- **OAuth apps**: the limit applies to the app, shared by everyone calling through it.
### Rate limit response headers
@@ -29,16 +48,6 @@ Every API response includes rate limit information following official [HTTP spec
You can use these headers to monitor your usage and implement proactive rate limit handling before receiving a 429 response.
### How rate limits are tracked
Your requests are identified and tracked using one of the following identifiers, in this order of priority:
1. **OAuth App ID** - If your request is authenticated via an OAuth application
2. **User ID** - If your request is authenticated with a personal access token
3. **IP Address** - If your request is unauthenticated (extracted from request headers)
Each identifier is combined with the scope (project or organization) to create a unique tracking key. This ensures that rate limits are isolated per user and per scope, preventing one project or organization from affecting another.
### Endpoint exceptions
Some endpoints have stricter rate limits than the standard 120 requests per minute to prevent abuse of resource-intensive operations:
@@ -55,8 +64,6 @@ Some endpoints have stricter rate limits than the standard 120 requests per minu
| `DELETE /v1/projects/:ref/config/custom-hostname` | 10 requests | 1 minute | These operations are expensive |
| `GET /v1/projects/:ref/config/vanity-subdomain` | 10 requests | 1 minute | These operations are expensive |
**Note:** The `GET /v1/projects/:ref/database/context` endpoint has dual rate limiting. You can make up to 10 requests per minute, but also no more than 1 request per second to prevent burst traffic.
Some endpoints have the standard 120 requests per minute but with different timeout durations:
| Endpoint | Limit | Duration | Reason |
@@ -65,7 +72,7 @@ Some endpoints have the standard 120 requests per minute but with different time
### Best practices
- **Monitor rate limit headers** - Check the `X-RateLimit-Remaining` header to see how many requests you have left. When it approaches 0, slow down your requests to avoid hitting the limit.
- **Implement exponential backoff** - When you receive a 429 response, wait before retrying. You can use the `X-RateLimit-Reset` header (seconds) to determine exactly how long to wait.
- **Batch operations** - Where possible, combine multiple operations into fewer API calls to reduce your request count.
- **Be mindful of expensive endpoints** - Analytics, database context, and domain endpoints have stricter limits, so use them judiciously.
- **Monitor rate limit headers**: Check the `X-RateLimit-Remaining` header to see how many requests you have left. When it approaches 0, slow down your requests to avoid hitting the limit.
- **Implement exponential backoff**: When you receive a 429 response, wait before retrying. You can use the `X-RateLimit-Reset` header (seconds) to determine exactly how long to wait.
- **Batch operations**: Where possible, combine multiple operations into fewer API calls to reduce your request count.
- **Be mindful of expensive endpoints**: Analytics, database context, and domain endpoints have stricter limits, so use them sparingly.
@@ -4,6 +4,7 @@ title: 'Supabase MCP Server'
subtitle: 'Connect your AI tools to Supabase using MCP'
description: 'Connect your AI tools to Supabase using MCP'
sidebar_label: 'MCP Server'
tocVideo: 1SMldLoOhbg
---
The [Model Context Protocol](https://modelcontextprotocol.io/introduction) (MCP) is a standard for connecting Large Language Models (LLMs) to platforms like Supabase. Once connected, your AI assistants can interact with and query your Supabase projects on your behalf.
+1
View File
@@ -4,6 +4,7 @@ title: 'AI & Vectors'
description: 'The best vector database is the database you already have.'
subtitle: 'The best vector database is the database you already have.'
hideToc: true
tocVideo: 6xchFWcHkaI
---
Supabase provides an open source toolkit for developing AI applications using Postgres and pgvector. Use the Supabase client libraries to store, index, and query your vector embeddings at scale.
+1
View File
@@ -3,6 +3,7 @@ id: 'ai-concepts'
title: 'Concepts'
description: 'Learn about embeddings within AI and vector applications.'
sidebar_label: 'Concepts'
tocVideo: 6xchFWcHkaI
---
Embeddings are core to many AI and vector applications. This guide covers these concepts. If you prefer to get started right away, see our guide on [Generating Embeddings](/docs/guides/ai/quickstarts/generate-text-embeddings).
@@ -4,6 +4,7 @@ title: 'Semantic search'
description: 'Learn how to search by meaning rather than exact keywords.'
subtitle: 'Learn how to search by meaning rather than exact keywords.'
sidebar_label: 'Semantic search'
tocVideo: 6xchFWcHkaI
---
Semantic search interprets the meaning behind user queries rather than exact [keywords](/docs/guides/ai/keyword-search). It uses machine learning to capture the intent and context behind the query, handling language nuances like synonyms, phrasing variations, and word relationships.
@@ -15,12 +15,12 @@ Supabase provides client libraries for the REST and Realtime APIs. Some librarie
| Dart/Flutter | [supabase-flutter](https://github.com/supabase/supabase-flutter/tree/main/packages/supabase_flutter) | [Docs](/docs/reference/dart/introduction) |
| Swift | [supabase-swift](https://github.com/supabase/supabase-swift) | [Docs](/docs/reference/swift/introduction) |
| Python | [supabase-py](https://github.com/supabase/supabase-py) | [Docs](/docs/reference/python/initializing) |
| C# | [supabase-csharp](https://github.com/supabase/supabase-csharp) | [Docs](/docs/reference/csharp/introduction) |
## Community libraries
| `Language` | `Source Code` | `Documentation` |
| ----------------------- | -------------------------------------------------------------------------------- | ---------------------------------------------------- |
| C# | [supabase-csharp](https://github.com/supabase-community/supabase-csharp) | [Docs](/docs/reference/csharp/introduction) |
| Go | [supabase-go](https://github.com/supabase-community/supabase-go) | |
| Kotlin | [supabase-kt](https://github.com/supabase-community/supabase-kt) | [Docs](/docs/reference/kotlin/introduction) |
| Ruby | [supabase-rb](https://github.com/supabase-community/supabase-rb) | |
+1 -1
View File
@@ -3,7 +3,7 @@ id: 'auth'
title: 'Auth'
description: 'Use Supabase to authenticate and authorize your users.'
subtitle: 'Use Supabase to authenticate and authorize your users.'
tocVideo: '6ow_jW4epf8'
tocVideo: 'Ufx6fdRMxjU'
---
Supabase Auth makes it easy to implement authentication and authorization in your app. We provide client SDKs and API endpoints to help you create and manage users.
+1
View File
@@ -2,6 +2,7 @@
id: 'auth-jwts'
title: 'JSON Web Token (JWT)'
subtitle: 'Information on how best to use JSON Web Tokens with Supabase'
tocVideo: 'Ufx6fdRMxjU'
---
A [JSON Web Token](https://jwt.io/introduction) is a type of data structure, represented as a string, that usually contains identity and authorization information about a user. It encodes information about its lifetime and is signed with a cryptographic key to make it tamper-resistant.
@@ -1,6 +1,7 @@
---
title: 'Password-based Auth'
subtitle: 'Allow users to sign in with a password connected to their email or phone number.'
tocVideo: 'Ufx6fdRMxjU'
---
Users often expect to sign in to your site with a password. Supabase Auth helps you implement password-based auth safely, using secure configuration options and best practices for storing and verifying passwords.
@@ -1,6 +1,7 @@
---
title: 'Social login'
description: 'Signing in with social accounts'
tocVideo: 'Ufx6fdRMxjU'
---
Social login (OAuth) is an open standard for authentication that allows users to sign in to one website or application using their credentials from another website or application. OAuth allows users to grant third-party applications access to their online accounts without sharing their passwords.
@@ -0,0 +1,109 @@
---
id: 'auth-third-party-custom-oidc'
title: 'Custom OIDC provider'
subtitle: 'Use any OIDC-compliant identity provider with your Supabase project'
---
Any identity provider that supports OpenID Connect (OIDC) can be used as a third-party authentication provider alongside Supabase Auth, or standalone, with your Supabase project. Use this guide for a provider that is not in the list of [supported providers](/docs/guides/auth/third-party/overview).
## Getting started
1. Check that your provider meets the [requirements](#requirements).
2. Add a Third-Party Auth integration with your provider's issuer URL in the [Dashboard](#add-the-integration-in-the-dashboard) or with the [Management API](#add-the-integration-with-the-management-api).
3. Add the `role` claim to the JWTs your provider issues.
4. Set up the Supabase client in your application.
## Requirements
Your provider must meet the [limitations](/docs/guides/auth/third-party/overview#limitations) of third-party auth:
1. It exposes an OIDC Issuer Discovery URL, served at `<issuer>/.well-known/openid-configuration`.
2. It signs JWTs with an asymmetric key and includes a `kid` header parameter. Symmetrically signed JWTs, such as HS256, are not supported.
3. Its JWTs contain a `role` claim. See [Assign the role claim](#assign-the-role-claim).
The issuer URL must use HTTPS. Your project reads the signing keys from the `jwks_uri` listed in the discovery document.
## Add the integration in the Dashboard
1. In the Dashboard, go to **Authentication** > **Sign In / Providers** > [**Third-Party Auth**](/dashboard/project/_/auth/third-party).
2. Click **Add provider** and select **Custom OIDC**.
3. Enter your provider's issuer URL in **Issuer URL**, for example `https://login.example.com`.
4. Click **Add provider**.
The provider appears in the Third-Party Auth list with its issuer URL. To remove it, delete it from the same list.
## Add the integration with the Management API
Create a [personal access token](/docs/guides/platform/personal-access-tokens), then call the [create third-party auth integration](/docs/reference/api/v1-create-project-tpa-integration) endpoint with your provider's issuer URL in the `oidc_issuer_url` field. To list or remove integrations, use the [list](/docs/reference/api/v1-list-project-tpa-integrations) and [delete](/docs/reference/api/v1-delete-project-tpa-integration) endpoints.
## Supabase CLI
Custom OIDC providers are not available in the Supabase CLI. There is no `supabase/config.toml` option for them.
## Assign the role claim
Your Supabase project inspects the `role` claim in every JWT sent to it, to assign the correct Postgres role when using the Data API, Storage or Realtime authorization. Without a `role` claim, requests run as the `anon` role.
Set `role` to `authenticated` for signed-in users. Use your provider's custom claims or token template feature to add it. See your provider's documentation for the steps.
## Set up the Supabase client library
Pass an `accessToken` async function that returns your provider's JWT for the current user, or `null` if there is no signed-in user:
```typescript
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(
'https://<supabase-project>.supabase.co',
'SUPABASE_PUBLISHABLE_KEY',
{
accessToken: async () => {
return getAccessTokenFromYourProvider()
},
}
)
```
Replace `getAccessTokenFromYourProvider` with the call your provider's SDK offers to get the current user's JWT.
## Using RLS policies
After the client sends your provider's JWT, use RLS policies to secure access to your project's database, Storage objects and Realtime channels.
### Identify the user
The `sub` claim identifies the user. `auth.uid()` casts `sub` to `uuid`, so it fails if your provider issues subjects that are not UUIDs. Read the claim directly instead:
```sql
create policy "Users can read their own rows"
on table_name
for select
to authenticated
using (user_id = (select auth.jwt()->>'sub'));
```
Here `user_id` must be a `text` column.
### Restrict access by issuer
Your project trusts every issuer you add, and `sub` values from different issuers can collide. If you use more than one issuer, or you also use Supabase Auth, add a restrictive policy that checks the `iss` claim:
```sql
create policy "Restrict access to trusted issuers"
on table_name
as restrictive
to authenticated
using (
(auth.jwt()->>'iss' = 'https://<project-ref>.supabase.co/auth/v1')
or
(auth.jwt()->>'iss' = 'https://login.example.com')
);
```
<Admonition type="danger">
Postgres has two types of policies: permissive and restrictive. This example uses a restrictive policy, so make sure you don't omit the `as restrictive` clause.
</Admonition>
For more on restrictive policies and on sharing the check across tables, Storage and Realtime, see the [Firebase Auth guide](/docs/guides/auth/third-party/firebase-auth#adding-an-extra-layer-of-security-to-your-projects-rls-policies-self-hosting-only).
@@ -11,6 +11,7 @@ Supabase has first-class support for these third-party authentication providers:
- [Auth0](/docs/guides/auth/third-party/auth0)
- [AWS Cognito (with or without AWS Amplify)](/docs/guides/auth/third-party/aws-cognito)
- [WorkOS](/docs/guides/auth/third-party/workos)
- [Custom OIDC provider](/docs/guides/auth/third-party/custom-oidc), for any other provider that supports OpenID Connect
You can use these providers alongside Supabase Auth, or on their own, to access the [Data API (REST and GraphQL)](/docs/guides/database/overview), [Storage](/docs/guides/storage), [Realtime](/docs/guides/storage) and [Functions](/docs/guides/functions) from your existing apps.
-31
View File
@@ -1,31 +0,0 @@
---
id: 'cli'
title: 'Local Dev with CLI'
description: 'Developing locally using the Supabase CLI.'
subtitle: 'Developing locally using the Supabase CLI.'
sidebar_label: 'Overview'
---
You can use the Supabase CLI to run the entire Supabase stack locally on your machine, by running `supabase init` and then `supabase start`. To install the CLI, read [the installation guide](/docs/guides/cli/getting-started#installing-the-supabase-cli).
The Supabase CLI provides tools to develop your project locally, deploy to the Supabase Platform, handle database migrations, and generate types directly from your database schema.
## Resources
<div className="grid md:grid-cols-12 gap-4 not-prose">
<div className="col-span-6">
<Link href="https://github.com/supabase/cli" passHref>
<GlassPanel icon={'/docs/img/icons/github-icon'} hasLightIcon={true} title="Supabase CLI">
The Supabase CLI provides tools to develop manage your Supabase projects from your local
machine.
</GlassPanel>
</Link>
</div>
<div className="col-span-6">
<Link href="https://github.com/supabase/setup-cli" passHref>
<GlassPanel icon={'/docs/img/icons/github-icon'} hasLightIcon={true} title="GitHub Action">
A GitHub action for interacting with your Supabase projects using the CLI.
</GlassPanel>
</Link>
</div>
</div>
+1
View File
@@ -1,6 +1,7 @@
---
title: 'Cron'
subtitle: 'Schedule Recurring Jobs with Cron Syntax in Postgres'
tocVideo: miRQPbIJOuQ
---
Supabase Cron is a Postgres Module that simplifies scheduling recurring Jobs with cron syntax and monitoring Job runs inside Postgres.
@@ -1,5 +1,6 @@
---
title: 'Install'
tocVideo: miRQPbIJOuQ
---
Install the Supabase Cron Postgres Module to begin scheduling recurring Jobs.
@@ -1,5 +1,6 @@
---
title: 'Quickstart'
tocVideo: miRQPbIJOuQ
---
<Admonition type="note">
@@ -29,7 +29,7 @@ You can get started with PostGIS by enabling the PostGIS extension in your Supab
1. Go to the [Database](/dashboard/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for `postgis` and enable the extension.
4. In the confirmation prompt select "Create a new schema" and name it `gis` for example.
4. In the confirmation dialog, review the default `extensions` schema and click **Enable**.
</TabPanel>
<TabPanel id="sql" label="SQL">
@@ -4,6 +4,7 @@ title: 'Database'
subtitle: 'Use Supabase to connect, manage, and secure your Postgres database.'
description: 'Use Supabase to connect, manage, and secure your Postgres database.'
sidebar_label: 'Overview'
tocVideo: 'C9kJwxhdw9A'
---
Every Supabase project gets a full [Postgres](https://www.postgresql.org/) database, not a Postgres abstraction. This database is the foundation that Auth, Storage, Realtime, and Edge Functions are built on, and Supabase manages daily database backups and offers point-in-time recovery on paid plans.
@@ -3,6 +3,7 @@ id: 'postgres-triggers'
title: 'Postgres Triggers'
description: 'Automatically execute SQL on table events.'
subtitle: 'Automatically execute SQL on table events.'
tocVideo: 'C9kJwxhdw9A'
---
In Postgres, a trigger executes a set of actions automatically on table events such as INSERTs, UPDATEs, DELETEs, or TRUNCATE operations.
@@ -16,7 +16,12 @@ Insert-only tables don't require a primary key or replica identity. Updates and
## Prepare DuckLake resources [#understand-the-ducklake-components]
DuckLake stores metadata in a Postgres catalog and data in object storage. With **Select Supabase projects**, choose a project for the catalog, then a project and bucket for storage. The catalog and storage can use the same project. Pipelines creates the connection credentials. With **Enter connection details**, you provide the catalog URL and storage credentials. You also need a compatible query engine to read the replicated data.
DuckLake stores metadata in a Postgres catalog and data in object storage. Pipelines offers two ways to set them up:
- **Use this Supabase project**: Pipelines uses this project's Postgres database as the catalog and a Storage bucket in the same project as object storage. It also creates the connection credentials.
- **Enter connection details**: You provide the catalog URL and the storage credentials.
To read the replicated data, you also need a compatible query engine.
| Component | Purpose |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
@@ -30,27 +35,24 @@ You can query replicated tables, but treat them and their underlying catalog and
Follow [Set up Pipelines](/docs/guides/database/replication/pipelines#setup-overview). In **Add pipeline**, select **DuckLake**, enter a **Pipeline name**, choose a **Publication**, and set **Initial sync**. Then choose how to configure the catalog and storage.
### Select Supabase projects [#use-supabase]
### Use this Supabase project [#use-supabase]
Choose Supabase projects for the Postgres catalog and Storage bucket. Pipelines creates the connection credentials when you create the destination.
Use the current Supabase project's Postgres database for the catalog and a Storage bucket in the same project. Pipelines creates the connection credentials when you create the destination.
Before you begin:
- Choose active, healthy, non-branch projects from the same organization for the catalog and storage. You can use the same project for both.
- Make sure your organization role can administer SQL in the catalog project and Storage in the storage project.
- Choose a Files bucket for DuckLake data. You can create a private bucket from the destination form.
- Choose an unused metadata schema name for this DuckLake. Pipelines creates the schema and its tables. Use only letters, numbers, and underscores. If the catalog project already uses the default `ducklake` schema for Warehouse, enter a different name.
- Keep catalog and storage in the same region when possible, near the [managed pipeline region](/docs/guides/database/replication/pipelines#region).
- Choose an unused metadata schema name for this DuckLake. Pipelines creates the schema and its tables. Use only letters, numbers, and underscores. If the project already uses the default `ducklake` schema for Warehouse, enter a different name.
To configure the destination:
1. Select **Select Supabase projects** under **Configuration method**.
2. Choose the **Catalog project** and **Metadata schema**.
3. Choose the **Storage project** and **Bucket**. Select **New bucket** at the bottom of the bucket list if you haven't created one yet.
1. Select **Use this Supabase project** under **Configuration method**.
2. Enter the **Metadata schema**.
3. Choose the **Bucket**. Select **New bucket** at the bottom of the bucket list if you haven't created one yet.
4. Optionally adjust **Pool size** under **Advanced settings**. It allows 1 to 6 concurrent DuckDB connections; the default is 4.
5. Click **Start pipeline**. Review any validation warnings, then confirm the estimated cost with **Create and start pipeline**.
Credential-provisioning warnings are expected before creation: catalog and Storage credentials are provisioned when you save the destination. Review the selected resources before proceeding.
Credential-provisioning warnings are expected before creation: catalog and Storage credentials are provisioned when you save the destination. Review the metadata schema and bucket before proceeding.
### Enter connection details [#custom-parameters]
@@ -62,7 +64,7 @@ Prepare the following resources:
2. An S3-compatible bucket and a dedicated prefix for this DuckLake.
3. Object-storage credentials that can list, read, write, and delete objects under that prefix. Delete access is required for managed file cleanup.
Choose an unused metadata schema name and a new data prefix for each destination. Pipelines creates the schema and its tables. Initialising a DuckLake catalog in that schema beforehand triggers a validation warning; reusing its schema or prefix can mix metadata or files from different DuckLakes.
Choose an unused metadata schema name and a new data prefix for each destination. Pipelines creates the schema and its tables. Initializing a DuckLake catalog in that schema beforehand triggers a validation warning; reusing its schema or prefix can mix metadata or files from different DuckLakes.
Select **Enter connection details** under **Configuration method**, then configure these fields:
@@ -91,7 +93,7 @@ A source `TRUNCATE` truncates the DuckLake table. A [table restart](/docs/guides
Connect DuckDB with its `ducklake` extension, or another compatible engine, to the same catalog and storage path. Query through the catalog; reading raw Parquet files can miss inlined changes, delete files, and the current snapshot.
If you selected Supabase projects, create separate read credentials for the catalog and Storage projects. The writer credentials generated for Pipelines aren't exposed. If you entered connection details, use separate read-only credentials when your catalog and storage provider support them.
If you use this Supabase project, create separate read credentials for its Postgres database and Storage. The writer credentials generated for Pipelines aren't exposed. If you enter connection details, use separate read-only credentials when your catalog and storage provider support them.
After attaching the catalog under an alias such as `my_ducklake`, source schemas and tables are available as qualified DuckLake tables:
@@ -161,7 +163,7 @@ For type changes, unsupported changes, and interrupted schema changes, see the s
| Issue | Resolution |
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Credential-provisioning warnings | Expected when you [select Supabase projects](#use-supabase) before saving. Review the selected resources. |
| Credential-provisioning warnings | Expected when you [use this Supabase project](#use-supabase) before saving. Review the metadata schema and bucket. |
| Catalog or storage validation fails | Check the [connection details](#custom-parameters), credentials, connectivity, and permissions for the configured prefix. Local `file://` paths are unsupported. |
| Metadata schema exists | Choose a new schema, unless intentionally reusing the same DuckLake and its corresponding data path. |
| Inserts work but updates or deletes fail | Check [replica identity and published columns](#source-table-requirements). |
+1 -1
View File
@@ -2,7 +2,7 @@
id: 'tables'
title: 'Tables and data'
description: 'Creating and using Postgres tables.'
video: 'https://www.youtube.com/v/TKwF3IGij5c'
tocVideo: 'C9kJwxhdw9A'
---
Learn what tables are and how to use them.
@@ -2,6 +2,7 @@
id: 'views'
title: 'Views'
description: 'Creating and using views in Postgres.'
tocVideo: 'C9kJwxhdw9A'
---
Learn what views are and when to use them.
@@ -7,27 +7,42 @@ You can deploy directly from GitHub on any plan — connect your repository and
Use branching to safely experiment with changes to your Supabase project.
Supabase branches create separate environments that spin off from your main project. You can use these branching environments to create and test changes like new configurations, database schemas, or features without affecting your production setup. When you're ready to ship your changes, merge your branch to update your production instance with the new changes.
Supabase branches create separate environments that spin off from your base project. You can use these branching environments to create and test changes like new configurations, database schemas, or features without affecting your production setup. When you're ready to ship your changes, merge your branch to update your production instance with the new changes.
## How branching works
- **Separate Environments**: Each branch is a separate environment with its own Supabase instance and API credentials.
- **Preview Branches**: Preview branches are ephemeral and best suited for focused testing. They are automatically deleted when a PR is merged or closed.
- **Persistent Branches**: Persistent branches are long-lived and recommended for environments like staging, QA, or development. They aren't automatically paused or deleted due to inactivity or when a PR is merged or closed.
- **Managing Branches**: You can create, review, and merge branches either automatically via our [GitHub integration](/docs/guides/deployment/branching/github-integration) or directly [through the dashboard](/docs/guides/deployment/branching/dashboard) (currently in beta). All branches show up in the branches page in the dashboard, regardless of how they were created.
- **Cloned from your main project**: Each new branch is created as a clone of your main project. It starts with that project's Edge Functions deployed and the configuration set.
- **Data-less by default**: By default, new branches do not start with any data or storage objects from your main project. This is meant to better protect your sensitive production data. To start your branches with data, you can use a [seed file](/docs/guides/deployment/branching/github-integration#seeding) if using the GitHub integration, or the [Include data](/docs/guides/deployment/branching/dashboard#include-production-data) option if you create the branch from the dashboard.
- **Managing Branches**: You can create, review, and merge branches either automatically via our [GitHub integration](/docs/guides/deployment/branching/github-integration) or directly [through the Supabase Dashboard](/docs/guides/deployment/branching/dashboard) (currently in beta). All branches show up in the branches page in the dashboard, regardless of how they were created.
- **Cloned from your base project**: Each new branch is created as a clone of your base project. It starts with that project's Edge Functions deployed and the configuration set.
- **Data-less by default**: By default, new branches do not start with any data or storage objects from your base project. This is meant to better protect your sensitive production data. To start your branches with data, you can use a [seed file](/docs/guides/deployment/branching/github-integration#seeding) if using the GitHub integration, or the [Include data](/docs/guides/deployment/branching/dashboard#include-production-data) option if you create the branch from the Supabase Dashboard.
## What a new branch starts with
Whether you create a branch from a pull request or from the Supabase Dashboard, Supabase creates a project with default settings then copies these settings from your base project:
- Postgres settings
- Connection pooler settings
- Auth, Data API, Realtime, and Storage settings
- SSL enforcement
- Network restrictions, when your base project has them
- Deployed Edge Functions
Auth secrets, such as OAuth provider secrets and SMTP passwords, get placeholder values instead. Set the real values with [branch secrets](/docs/guides/deployment/branching/configuration#managing-secrets-for-branches). Supabase also turns on Database Webhooks for every branch.
The database schema isn't cloned. A GitHub-connected branch builds it from the [migrations in your repository](/docs/guides/deployment/branching/github-integration#migrations). A dashboard branch builds it from your [base project's migration history](/docs/guides/deployment/branching/dashboard#where-a-dashboard-branch-gets-its-schema). The branch is ready when the settings, the schema, and the Edge Functions are all in place.
## Deploying to production
When you merge any branch into your main project, Supabase automatically runs a deployment workflow to deploy your changes to production. The deployment workflow is expressed as a Directed Acyclic Graph where each node represents one of the following deployment steps.
When you merge any branch into your base project, Supabase automatically runs a deployment workflow to deploy your changes to production. The deployment workflow is expressed as a Directed Acyclic Graph where each node represents one of the following deployment steps.
1. **Clone** - Checks out your repository at the specified git branch (optional for [Branching via Dashboard](/docs/guides/deployment/branching/dashboard))
2. **Pull** - Retrieves database migrations from your main project (also initialises the migration history table when Branching via Dashboard)
2. **Pull** - Retrieves database migrations from your base project (also initialises the migration history table when Branching via Dashboard)
3. **Health** - Waits up to 2 minutes for all Supabase services on your branch to be running and healthy, including Auth, API, Database, Storage, and Realtime
4. **Configure** - Updates service configurations based on your config.toml file (only available for [Branching via GitHub](/docs/guides/deployment/branching/github-integration))
5. **Migrate** - Applies pending database migrations and vault secrets to your branch
6. **Seed** - Runs seed files to populate your branch with initial data (must be [enabled in config.toml](/docs/guides/deployment/branching/configuration#branch-configuration-with-remotes) for persistent branches)
7. **Deploy** - Deploys any changed Edge Functions and updates function secrets
If a parent deployment step fails, all dependent child steps will be skipped. For instance, if your database migrations failed at step 5, our runner will not seed your branch because step 6 is skipped. If you are using GitHub integration, the same deployment workflow will be run on every commit pushed to your git branch.
If a parent deployment step fails, all dependent child steps are skipped. For instance, if your database migrations fail at step 5, our runner doesn't seed your branch because step 6 is skipped. If you are using GitHub integration, the same deployment workflow runs on every commit pushed to your git branch. To check each step's status in the Supabase Dashboard, see [Monitoring deployments](/docs/guides/deployment/branching/troubleshooting#monitoring-deployments).
@@ -3,17 +3,17 @@ title: 'Branching via the dashboard'
subtitle: 'Create, manage, review, and merge branches directly in the dashboard'
---
You can create, manage, review, and merge Supabase branches directly via the dashboard. This is useful for quick testing, prototyping, or when you prefer to work in a no-code way. You can also connect a Supabase branch to a GitHub branch at a later time if needed.
You can create, manage, review, and merge Supabase branches directly in the Supabase Dashboard. This is useful for quick testing, prototyping, or when you prefer to work in a no-code way. You can also connect a Supabase branch to a GitHub branch at a later time if needed.
<Admonition type="note" title="Public Alpha">
Branch management via the dashboard is currently in public alpha. Features and functionality may change.
Branch management in the Supabase Dashboard is currently in public alpha. Features and functionality may change.
</Admonition>
## How Branching works
You can do the following directly from the Supabase dashboard:
You can do the following directly from the Supabase Dashboard:
- Create preview branches
- Make changes to your public schema or edge functions
@@ -41,7 +41,11 @@ Once you've enabled the feature, you can create a new branch:
1. Click the arrows next to the branch name in the top menu bar. (The top menu bar has the format `YOUR_ORGANIZATION / YOUR_PROJECT / CURRENT_BRANCH_NAME`.)
2. Click `Create branch`.
The new branch is a clone of your base project. It starts with the project's schema, Edge Functions, and the configuration set.
The new branch is a clone of your base project. It starts with the project's schema, Edge Functions, and the configuration set. For the full list of what it inherits, see [What a new branch starts with](/docs/guides/deployment/branching#what-a-new-branch-starts-with).
### Where a dashboard branch gets its schema
A dashboard branch has no git branch to read migrations from. Instead, it reads your base project's migration history and applies each entry as a migration. The branch ends up with the same schema as your base project. If your base project has no migration history, the branch dumps the base project's schema and uses the dump as its first migration.
### Include production data
@@ -81,7 +85,7 @@ When reviewing a merge request you may see a notice at the top of the page askin
There are a few limitations you should be aware of before deciding to use branching without git.
- Custom roles created through the dashboard are not captured on branch creation
- Custom roles created through the Supabase Dashboard are not captured on branch creation
- Branches can only be merged to main; merging between preview branches is not supported
- If your branch is out of date, you can pull in latest changes from main, but keep in mind that all functions will be overwritten
- Deleting functions must be done manually on main branch
@@ -43,7 +43,7 @@ You will be using the [Supabase CLI](/docs/guides/local-development) to initiali
<StepHikeCompact.Step step={2}>
<StepHikeCompact.Details title="Pull your database migration" fullWidth>
Pull your database changes using `supabase db pull`. To get your database connection string, go to your project dashboard, click [Connect](/dashboard/project/_?showConnect=true&method=session) and look for the Session pooler connection string.
Pull your database changes using `supabase db pull`. To get your database connection string, open the Supabase Dashboard, click [Connect](/dashboard/project/_?showConnect=true&method=session) and look for the Session pooler connection string.
```markdown
supabase db pull --db-url <db_connection_string>
@@ -83,13 +83,23 @@ Enable the **Automatic branching** option in your GitHub Integration configurati
When a new branch is created in GitHub, a corresponding branch is created in Supabase. (You can enable the **Supabase changes only** option to only create Supabase branches when Supabase files change.)
Every Supabase branch, preview or persistent, is created as a clone of your base project. The new branch starts with the Edge Functions and configuration of that project. Its database schema is not cloned. Instead, it is built from the migrations you commit to your repository.
Every Supabase branch, preview or persistent, is created as a clone of your base project. The new branch starts with the Edge Functions and configuration of that project. Its database schema is not cloned. Instead, it is built from the migrations you commit to your repository. For the full list of what a branch inherits, see [What a new branch starts with](/docs/guides/deployment/branching#what-a-new-branch-starts-with).
### What runs on each push
After Supabase creates the branch and copies your base project's settings, it runs the branching workflow against the files in your repository. The workflow applies your `config.toml` first, then runs any migrations the branch hasn't applied yet. After that it seeds the database and Storage buckets, and finally deploys your Edge Functions. On a persistent branch, including your production branch, the `config.toml` and seed steps apply only when a `[remotes]` block names that branch, as described in [Configuration](#configuration). The same workflow runs again on every push to the git branch. You don't need a GitHub Action to deploy migrations or sync `config.toml` to a branch.
For what each step does, see [Deploying to production](/docs/guides/deployment/branching#deploying-to-production). To check a step's status and read its logs, see [Monitoring deployments](/docs/guides/deployment/branching/troubleshooting#monitoring-deployments).
### Configuration
You can test configuration changes on your Preview Branch by configuring the `config.toml` file in your Supabase directory. See the [Configuration docs](/docs/guides/deployment/branching/configuration) for more information.
Your branch starts with the configuration of your base project. The settings in your `config.toml` file are applied on top of that clone.
Supabase applies the settings in your `config.toml` on top of the configuration copied from your base project, and where the two differ, your repository wins.
The `configure` step compares the `[db]`, `[api]`, `[auth]`, `[storage]`, and `[experimental]` sections of `config.toml` with the branch's current settings and updates the ones that differ. The migrate, seed, and deploy steps read the other sections, such as `[functions]` and `[db.seed]`. If your repository has no `config.toml`, the step only turns on Database Webhooks.
On a persistent branch, including your production branch, the step runs only when a `[remotes]` block names that branch's project ID. For the `[remotes]` syntax, see [Remote-specific configuration](/docs/guides/deployment/branching/configuration#remote-specific-configuration).
A comment is added to your PR with the deployment status of your preview branch.
@@ -97,11 +107,18 @@ A comment is added to your PR with the deployment status of your preview branch.
The migrations in the `migrations` subdirectory of your Supabase directory are automatically run when the branch is created. Each later commit runs only the migrations that haven't been applied yet.
The `migrate` step compares the files in `supabase/migrations` with the branch's migration history and applies every file without a history entry. Before it runs them, it saves the Vault secrets declared under `[db.vault]` to the branch. Keep two cases in mind:
- A migration file with a timestamp older than the latest applied migration still runs and the step finishes with a warning.
- A version in the branch's migration history with no matching file fails the step.
To stop branching from running migrations, set `enabled = false` under `[db.migrations]` in `config.toml`.
If your project uses [declarative schemas](/docs/guides/local-development/declarative-database-schemas), the files in `supabase/schemas/` are not applied by branching. Run `supabase db schema declarative sync` to generate a migration from your schema changes, and commit the generated migration alongside your schema files.
Branching runs each migration file inside a single transaction and does not honor the `-- pg-delta: transaction=false` directive. A migration that can't run in a transaction (for example, one that uses `create index concurrently`, or a [`pg-delta`](/docs/guides/local-development/diff-engines) file that carries the directive) applies with `supabase db push` but fails when branching deploys it.
If you want to rerun existing migrations, reset the branch from the Supabase dashboard to start from scratch. Note that existing data on your branch will also be dropped by a reset.
If you want to rerun existing migrations, reset the branch from the Supabase Dashboard to start from scratch. Note that existing data on your branch will also be dropped by a reset.
### Seeding
@@ -111,6 +128,15 @@ You can seed your Preview Branch with sample data using the `seed.sql` file in y
Data changes in your seed files are not merged to production.
### Edge Functions
Edge Functions reach your branch in the `deploy` step, the last step of the workflow. The step saves the function secrets declared under `[edge_runtime.secrets]` then deploys functions:
- If your repository has a `supabase/functions` directory, the step deploys the functions declared in `config.toml` under `[functions.<slug>]`. If the directory has functions but `config.toml` declares none, the step deploys nothing and finishes with a warning.
- If your repository has no functions directory, the step copies the functions deployed on your base project. `config.toml` can still disable a copied function or change its JWT verification.
A function is uploaded again only when it changed. For each function, the step compares the checksum of the new bundle and the JWT verification setting against the version already deployed on the branch. If both are the same, the step skips that function.
## Deploying changes to production
Enable the **Deploy to production** option in your GitHub Integration configuration to automatically deploy changes when you push or merge to production branch.
@@ -10,11 +10,23 @@ This guide covers common issues you might encounter when using Supabase branchin
To check deployment status and troubleshoot failures:
1. Go to your project dashboard
1. Open the Supabase Dashboard
2. Navigate to "Manage Branches"
3. Click on your branch to view deployment logs
4. Check the "View logs" section for detailed error messages
Each step in a workflow run reports one of these statuses:
| Status | Meaning |
| --------- | ----------------------------------------------------------------------------------- |
| `CREATED` | The step hasn't started. |
| `RUNNING` | The step is in progress. |
| `EXITED` | The step succeeded. |
| `PAUSED` | The step finished with a warning, or was skipped on purpose. Later steps still run. |
| `DEAD` | The step failed. Steps that depend on it don't run. |
A failed health check is a warning. The `health` step shows `PAUSED` and the workflow continues. A `DEAD` `migrate` step stops the `seed` and `deploy` steps.
For programmatic monitoring, you can use the [Management API](https://api.supabase.com/api/v1#tag/environments/post/v1/projects/{ref}/branches) to poll branch status.
For detailed troubleshooting guidance, see our [Troubleshooting guide](/docs/guides/deployment/branching/troubleshooting).
@@ -29,7 +41,7 @@ To fix this, push the latest changes, then delete the preview branch in Supabase
The new preview branch is a fresh clone of your base project and is reseeded from the `./supabase/seed.sql` file by default. Any additional data changes made on the old preview branch are lost.
To rerun migrations that your base project has already applied, reset the branch from the Supabase dashboard instead. A reset reruns all migrations in sequential order and drops existing data on the branch.
To rerun migrations that your base project has already applied, reset the branch from the Supabase Dashboard instead. A reset reruns all migrations in sequential order and drops existing data on the branch.
### Deployment failures
@@ -123,6 +135,8 @@ If configuration changes aren't applying:
1. **Syntax errors**: Validate your `config.toml` syntax
2. **Git sync**: Ensure changes are committed and pushed
3. **Branch refresh**: Try deleting and recreating the branch
4. **Persistent branch**: Configuration runs on a persistent branch, including your production branch, only when a `[remotes]` block names its project ID. For the `[remotes]` syntax, see [Remote-specific configuration](/docs/guides/deployment/branching/configuration#remote-specific-configuration)
5. **Section not applied by branching**: The `configure` step applies only the `[db]`, `[api]`, `[auth]`, `[storage]`, and `[experimental]` sections. For which steps read the other sections, see [Configuration](/docs/guides/deployment/branching/github-integration#configuration)
### Secrets not available
@@ -172,7 +186,7 @@ Remember that preview branch data:
If you're still experiencing issues:
1. **Check logs**: Review branch logs in the dashboard
1. **Check logs**: Review branch logs in the Supabase Dashboard
2. **Community**: Ask in [GitHub discussions](https://github.com/orgs/supabase/discussions/18937)
3. **Support**: Contact support for project-specific issues
4. **Documentation**: Review the latest documentation for updates
+1 -1
View File
@@ -4,7 +4,7 @@ title: 'Edge Functions'
description: 'Run TypeScript functions globally at the edge.'
subtitle: 'Run TypeScript functions globally at the edge.'
sidebar_label: 'Overview'
tocVideo: 'za_loEtS4gs'
tocVideo: 'EQ5h3NSWMbk'
---
Edge Functions are server-side TypeScript functions, distributed globally at the edge—close to your users. They can be used for listening to webhooks or integrating your Supabase project with third-parties [like Stripe](https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/stripe-webhooks). Edge Functions are developed using [Deno](https://deno.com), which offers a few benefits to you as a developer:
@@ -3,7 +3,7 @@ id: 'architecture'
title: 'Edge Functions Architecture'
description: 'Guide to Supabase Edge Functions: Architecture and How They Work'
subtitle: 'Understanding the Architecture of Supabase Edge Functions'
tocVideo: 'za_loEtS4gs'
tocVideo: 'EQ5h3NSWMbk'
---
This guide explains the architecture and inner workings of Supabase Edge Functions, based on the concepts demonstrated in the video "Supabase Edge Functions Explained". Edge functions are serverless compute resources that run at the edge of the network, close to users, enabling low-latency execution for tasks like API endpoints, webhooks, and real-time data processing. This guide breaks down Edge Functions into key sections: an example use case, deployment process, global distribution, and execution mechanics.
@@ -115,6 +115,8 @@ To use private npm packages, create a `.npmrc` file within your function’s own
<Admonition type="note">This feature requires Supabase CLI version 1.207.9 or higher.</Admonition>
Your function's directory must also contain a `deno.json` or `package.json` file. The file can be empty. If neither file is present, the `.npmrc` file is ignored. This matches the Deno CLI behavior.
```bash
└── supabase
└── functions
@@ -3,7 +3,7 @@ id: 'functions-deploy'
title: 'Deploy to Production'
description: 'Deploy your Edge Functions to your remote Supabase Project.'
subtitle: 'Deploy your Edge Functions to your remote Supabase Project.'
tocVideo: '5OWH9c4u68M'
tocVideo: 'EQ5h3NSWMbk'
---
Once you have developed your Edge Functions locally, you can deploy them to your Supabase project.
@@ -3,7 +3,7 @@ id: 'development-environment'
title: 'Development Environment'
description: 'Get the best Edge Functions experience with the right local developer environment.'
subtitle: 'Set up your local development environment for Edge Functions.'
tocVideo: 'lFhU3L8VoSQ'
tocVideo: 'EQ5h3NSWMbk'
---
<Admonition type="note">
@@ -3,6 +3,7 @@ id: 'functions-quickstart-dashboard'
title: 'Getting Started with Edge Functions (Dashboard)'
description: 'Get started with Supabase Edge Functions.'
subtitle: 'Learn how to create, test, and deploy your first Edge Function using the Supabase Dashboard.'
tocVideo: 'EQ5h3NSWMbk'
---
Supabase allows you to create Supabase Edge Functions directly from the Supabase Dashboard, making it easy to deploy functions without needing to set up a local development environment. The Edge Functions editor in the Dashboard has built-in syntax highlighting and type-checking for Deno and Supabase-specific APIs.
@@ -3,6 +3,7 @@ id: 'functions-quickstart'
title: 'Getting Started with Edge Functions'
description: 'Get started with Supabase Edge Functions.'
subtitle: 'Learn how to create, test, and deploy your first Edge Function using the Supabase CLI.'
tocVideo: 'EQ5h3NSWMbk'
---
This guide walks you through creating, testing locally, deploying, and invoking a Supabase Edge Function using the CLI. By the end, you'll have a working function running on Supabase's global edge network.
@@ -3,6 +3,7 @@ id: 'functions-secrets'
title: 'Environment variables'
description: 'Set, read, and deploy Edge Function secrets.'
subtitle: 'Store API keys and other secrets where your Edge Functions can read them.'
tocVideo: 'EQ5h3NSWMbk'
---
Local development and production load secrets differently, so set them in both.
Loaded 100 of 1941 files, more files were not shown because too many files have changed in this diff. Show more