chore(docs) Retire supa-mdx-lint (#50602)

Closes
[DOCS-1289](https://linear.app/supabase/issue/DOCS-1289/get-the-linter-to-fix-what-it-flags-or-retirereplace-the-linter)

Stacked on #50600, which points contributors at the authoring skills.
Merge that one first.

## Problem

Contributors experienced friction with the linter. They felt nickle and
dimed for tiny nits and felt detracted from the work itself. PRs would
become noisy with tiny one-word suggestions.

Additionally, our homegrown linter is not very intelligent, causing
frequent overrides.

## Solution

This removes the linter entirely in favor of directing contributors to
use SKILLS instead.

The removal entails...

- **CI.** Delete the three `docs_lint` workflows: the PR check, the
external-PR comment companion, and the nightly `--fix` bot. Drop the
stale `zizmor.yml` ignore entry for the deleted workflow.
- **Tooling.** Delete `supa-mdx-lint.config.toml` and the 14 rule files.
Drop the `lint:mdx` script and the `@supabase/supa-mdx-lint` dependency
from docs, learn, and ui-library, and regenerate the lockfile.
- **Content.** Remove the 181 directives. A separate commit carries
Prettier's reformatting of the tables and blank lines those comments had
suppressed, so the deletion commit stays readable. No prose changes.
- **Style guide.** The word list states each rule directly instead of
describing what the linter flagged. Every term survives, including the
phrase groups that mirrored `Rule004ExcludeWords`.
- **Skills.** `write-the-docs`, `edit-the-docs`, and `review-the-docs`
drop `pnpm lint:mdx` from their self-review commands and check the word
list directly. `ask-the-docs`'s CI reference drops both workflows.

## Manual testing

1. Run `git grep -i supa-mdx-lint -- . ':!pnpm-lock.yaml'`. No matches.
2. Run `pnpm install --frozen-lockfile --lockfile-only`. It passes, so
the lockfile matches the three trimmed manifests.
3. Run `git diff master...HEAD --name-only --diff-filter=ACMR | grep -E
'\.(md|mdx)$' | xargs npx prettier --config prettier.config.mjs
--check`. All changed markdown passes.
4. Open the [reformatted filter
table](https://docs-git-docs-retire-mdx-linter-supabase.vercel.app/docs/guides/observability/logs#filter-events)
on the preview and compare it with
[production](https://supabase.com/docs/guides/observability/logs#filter-events).
The table renders the same.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Documentation**
* Documentation guidance now uses manual prose and terminology review
with the shared word list.
* Clarified storage configuration and common Realtime channel mistakes.
* Improved table formatting, text wrapping, and selected reference
links.
  * Updated documentation authoring and review guidance.

* **Chores**
* Retired automated MDX linting from workflows and local validation
commands.
* Removed lint-suppression markers throughout documentation without
changing instructions.
  * Added targeted documentation review guidance for pull requests.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Miranda Limonczenko authored and GitHub committed 2026-09-22 10:00:41 -07:00
1 parent f65ee588c1
commit 7ce4ee53ae
100 files changed
+127 -2043

No files matched your search

+1 -1
View File
@@ -86,7 +86,7 @@ at hand — they cite each other where context matters.
| [`reference/llm-agent-surface.md`](./reference/llm-agent-surface.md) | Audience routing, `llms.txt`, content negotiation, bulk exports. |
| [`reference/llm-agent-parity.md`](./reference/llm-agent-parity.md) | HTML↔markdown fidelity (e.g. AI prompts), search caveat, agent onboarding guides, in-flux wiring. |
| [`reference/federated-docs.md`](./reference/federated-docs.md) | How docs pulls markdown from external repos at build time. Routes, `pageMap`, remark/rehype plugins, link transforms, known failure modes. |
| [`reference/ci-and-lint.md`](./reference/ci-and-lint.md) | GitHub Actions on every PR — `docs_lint`, `Docs Tests`, typecheck, prettier, Vercel preview gate. Where to add a check before creating a new one. |
| [`reference/ci-and-lint.md`](./reference/ci-and-lint.md) | GitHub Actions on every PR — `Docs Tests`, typecheck, prettier, Vercel preview gate. Where to add a check before creating a new one. |
| [`reference/management-api-reference.md`](./reference/management-api-reference.md) | Management API OpenAPI → reference generation, including scoped PAT permission tables; why not to swap in Scalar/Redoc. |
| [`reference/graphql-endpoint.md`](./reference/graphql-endpoint.md) | The `/api/graphql` endpoint under `apps/docs/resources/` — per-query folder layout, `rootSchema.ts`, connection/field utils, and the steps to add a new top-level query. |
| [`reference/search-embeddings.md`](./reference/search-embeddings.md) | The `scripts/search/` embeddings pipeline behind `searchDocs` — content sources, processing flow, change detection, and the `page` / `page_section` tables. |
@@ -46,7 +46,6 @@ building parallel ones.
| Code samples in MDX | `$CodeSample` directive |
| Build steps | `prebuild` / `postbuild` chain in `apps/docs/package.json` |
| CI checks | Existing workflows under `.github/workflows/`. See [`ci-and-lint.md`](./ci-and-lint.md). |
| Lint rules for MDX content | `supa-mdx-lint` configuration — extend it, don't add a new lint job |
If something close to what you need already exists, **the default is to
extend it**, not to build alongside.
@@ -90,8 +89,8 @@ Antipatterns to avoid:
covers the pattern — compose at the call site instead.
- New custom build steps that run alongside the existing `prebuild` /
`postbuild` chain when a hook already exists.
- A new CI workflow when `docs_lint`, `Docs Tests`, or the existing
typecheck/prettier jobs could absorb the check. See
- A new CI workflow when `Docs Tests` or the existing typecheck/prettier jobs
could absorb the check. See
[`ci-and-lint.md`](./ci-and-lint.md).
- A new content vocabulary (custom front-matter block, novel MDX directive,
new YAML schema) when a React component + partial would express the same
@@ -194,15 +194,14 @@ markdown string to substitute.
See [`ci-and-lint.md`](./ci-and-lint.md) for the full CI surface. Local
commands:
| Tool | Where | What it catches |
| --------------------------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------- |
| `pnpm test:local:unwatch <path>` (from `apps/docs`) | per-test | Vitest suite for `lib/` and `data/` schemas; needs local Supabase + DB reset first — see `apps/docs/AGENTS.md` |
| `pnpm format` | repo root | Prettier — run before opening a PR |
| `pnpm lint --filter=docs` | repo root | ESLint over `apps/docs` |
| `pnpm typecheck` | repo root | TS across packages |
| `pnpm build --filter=docs` | repo root | Includes markdown generation; failures here block release |
| `pnpm lint:mdx` | `apps/docs` | MDX content lint (whole `content/` tree) |
| Typos check (`.github/workflows/avoid-typos.yml`) | CI only | `runner / misspell` job at error severity — no local command; fix flagged words before merge |
| Tool | Where | What it catches |
| --------------------------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------- |
| `pnpm test:local:unwatch <path>` (from `apps/docs`) | per-test | Vitest suite for `lib/` and `data/` schemas; needs local Supabase + DB reset first — see `apps/docs/AGENTS.md` |
| `pnpm format` | repo root | Prettier — run before opening a PR |
| `pnpm lint --filter=docs` | repo root | ESLint over `apps/docs` |
| `pnpm typecheck` | repo root | TS across packages |
| `pnpm build --filter=docs` | repo root | Includes markdown generation; failures here block release |
| Typos check (`.github/workflows/avoid-typos.yml`) | CI only | `runner / misspell` job at error severity — no local command; fix flagged words before merge |
Before adding a custom lint job, check whether the existing one can absorb
the check (see [`adding-features.md`](./adding-features.md) "Reuse
@@ -12,8 +12,6 @@ Before adding a new lint job or CI check, **scan this list first** — see
```
PR opened / updated
│
├── docs_lint (MDX/content linting; required)
├── docs_lint_comment_external (posts results as PR comments for external PRs)
├── Docs Tests (pnpm test:docs on relevant docs code/spec changes)
├── TypeScript & Lint (tsc + eslint)
├── Prettier (format check)
@@ -29,12 +27,7 @@ Merge to master
Workflows run in parallel against any PR touching the repo:
### 1. `docs_lint`
Primary docs-specific CI check. MDX/content linting for the docs. **Required
check before merging.** Backed by `supa-mdx-lint`.
### 2. Docs Tests (`docs-tests.yml`)
### 1. Docs Tests (`docs-tests.yml`)
Triggered on relevant docs code/spec changes, including the generated scoped
PAT partials and their shared permission catalog. Runs on a Blacksmith 4-vCPU
@@ -49,29 +42,24 @@ Ubuntu runner with concurrency controls to cancel stale builds.
- Run `pnpm run test:docs` (with dummy GitHub OAuth env vars to prevent local
Supabase startup errors).
### 3. TypeScript & Lint (`typecheck.yml`)
### 2. TypeScript & Lint (`typecheck.yml`)
TypeScript type checking and ESLint across the monorepo.
### 4. Prettier (`prettier.yml`)
### 3. Prettier (`prettier.yml`)
Format checking across the whole repo including `apps/docs`.
### 5. `docs_lint_comment_external`
Companion to `docs_lint` that posts lint results as PR comments for external
contributors.
### 6. Authorize Vercel Deploys
### 4. Authorize Vercel Deploys
Gates Vercel preview deployment on a GitHub-side check first. Prevents
arbitrary forks from triggering Vercel builds.
### 7. reviewdog
### 5. reviewdog
Inline code review annotations via reviewdog.
### 8. Validate pull request
### 6. Validate pull request
PR metadata validation (title format, labels, etc.).
@@ -102,8 +90,9 @@ builds/deploys the Next.js site to their CDN.
Before adding a new GitHub Actions workflow:
1. **Can `docs_lint` absorb it?** — most MDX/content checks belong inside
`supa-mdx-lint` configuration, not as a new workflow.
1. **Is it a prose or terminology check?** — it belongs in the authoring
skills, not in a workflow. The repo ran a blocking MDX linter and retired
it.
2. **Can `Docs Tests` absorb it?** — TypeScript / vitest checks for new
functionality fit here.
3. **Is it cross-cutting?** — typecheck, prettier, and reviewdog already
+2 -2
View File
@@ -13,7 +13,7 @@ description: >-
Improves **existing** Supabase docs pages: structure, order, connective text, and clarity.
**Not this skill:** [`write-the-docs`](../write-the-docs/SKILL.md) drafts net-new content or product-grounded rewrites from intent and code. [`review-the-docs`](../review-the-docs/SKILL.md) covers lint, build, and PR triage.
**Not this skill:** [`write-the-docs`](../write-the-docs/SKILL.md) drafts net-new content or product-grounded rewrites from intent and code. [`review-the-docs`](../review-the-docs/SKILL.md) covers build and PR triage.
**Output is one pull request, with one change type per commit.** A reviewer reads the style diff apart from the structure diff without holding several PRs in their head. Split into a stack of PRs only when the requester asks for one, or approves the split you offer because the diff turned out large. Phase 0 covers when to raise it, and [reference/stacked-prs.md](reference/stacked-prs.md) covers the mechanics.
@@ -196,7 +196,7 @@ Run this per change type, before you submit the commit or branch that carries it
**Frontmatter `title`.** It follows the same sentence-case rule as a heading. Renaming it moves a navigation label and a search entry, not just a line of prose, so it clears this same gate and lands in PR 2 rather than PR 1.
**Lint and format.** Follow [`write-the-docs/reference/drafting-mechanics.md`](../write-the-docs/reference/drafting-mechanics.md). Then run the [`review-the-docs`](../review-the-docs/SKILL.md) local self-review: `pnpm lint:mdx`, plus `pnpm build:guides-markdown` when a guide, explainer, or tutorial changed.
**Format and build.** Follow [`write-the-docs/reference/drafting-mechanics.md`](../write-the-docs/reference/drafting-mechanics.md). Then run the [`review-the-docs`](../review-the-docs/SKILL.md) local self-review, plus `pnpm build:guides-markdown` when a guide, explainer, or tutorial changed.
`build:guides-markdown` writes `apps/docs/public/markdown/manifest.json`, which the repo tracks and commits as `[]`. Discard that file before committing. It's a build artifact, not part of the edit.
+5 -10
View File
@@ -59,9 +59,6 @@ git diff --name-only master...HEAD
3. **Run type-specific checks** from the matching sections below on the current branch (no checkout step). Typical commands:
```bash
# Content / tutorial MDX (lints the whole content/ tree; no per-file scoping)
cd apps/docs && pnpm lint:mdx
# Pipeline / schema handler
cd apps/docs && pnpm build:guides-markdown
# inspect public/markdown/guides/ for affected pages
@@ -205,13 +202,14 @@ Verify both guides and reference output when `generate-reference-markdown.ts` or
MDX prose, partials, navigation — no pipeline or example changes.
```bash
cd apps/docs
pnpm lint:mdx # lints the whole content/ tree; filter the output to your changed paths
```
Check the prose against [`apps/docs/CONTRIBUTING.md`](../../../apps/docs/CONTRIBUTING.md) and
[`apps/docs/WORD_LIST.md`](../../../apps/docs/WORD_LIST.md) yourself. No CI or local
check covers terminology. CodeRabbit reviews style, terminology, and structure
on `apps/docs/content/**/*.mdx`, but only once the PR is open.
Checklist:
- [ ] Prose follows CONTRIBUTING.md and the word list
- [ ] Frontmatter valid (`title`, `description` where required)
- [ ] Internal links resolve (`/docs/guides/...`, not broken anchors)
- [ ] `$CodeSample` paths match existing example directories
@@ -228,9 +226,6 @@ Compare PR preview URL (from Vercel/deployment comment) against production for v
Tutorial MDX plus matching example app. **Read [`work-linear-issue`](https://github.com/supabase/docs-agent-skills/blob/main/.claude/skills/work-linear-issue/SKILL.md)** for full platform E2E — review is not complete without it when auth flows are involved.
```bash
# MDX lint
cd apps/docs && pnpm lint:mdx # then check output for content/guides/getting-started/tutorials/<path>
# Example build (from work-linear-issue)
cd examples/<example-dir>
npm install && npm run build
+3 -3
View File
@@ -5,14 +5,14 @@ description: >-
sandbox (runner container + local Supabase stack via `supabase start`). Use
after Draft or during Self-review when asked to test the docs, fact-check
CLI/SQL/code samples, or produce a verification report for a docs PR.
Complements review-the-docs lint/build checks; does not replace them.
Complements review-the-docs build and review checks; does not replace them.
---
# Test the docs
Runs procedural docs content **inside disposable containers**, not on the host shell and not against production. Produces a verification report for the PR body / self-review note.
For lint, markdown rebuilds, example-app triage, and PR review, use [`review-the-docs`](../review-the-docs/SKILL.md). For Frame/Shape and cross-repo product lookup, use [`pm-the-docs`](../pm-the-docs/SKILL.md).
For markdown rebuilds, example-app triage, and PR review, use [`review-the-docs`](../review-the-docs/SKILL.md). For Frame/Shape and cross-repo product lookup, use [`pm-the-docs`](../pm-the-docs/SKILL.md).
## When to invoke
@@ -92,5 +92,5 @@ Write a verification report per [reference/verification-report.md](reference/ver
## Related skills
- [`write-the-docs`](../write-the-docs/SKILL.md) — Draft; hands off here before PR
- [`review-the-docs`](../review-the-docs/SKILL.md) — lint/build/classify; consumes verification report
- [`review-the-docs`](../review-the-docs/SKILL.md) — build/classify; consumes verification report
- [`pm-the-docs`](../pm-the-docs/SKILL.md) — Frame/Shape; universe for cross-repo product lookup
+2 -2
View File
@@ -88,10 +88,10 @@ Re-read [`apps/docs/CONTRIBUTING.md`](../../../apps/docs/CONTRIBUTING.md) and [`
This skill stops at a reviewable draft. It does not open worktrees or PRs itself:
- **Offer** [`test-the-docs`](../test-the-docs/SKILL.md) when the draft includes runnable procedural snippets. Ask before starting verification. Gate prerequisites **per artifact class** (Docker Compose stack profile for DB/API artifacts; examples profile / Node in-runner for `example-app`). If declined, or a required prerequisite for that class is missing, record `deferred` for those artifacts only and continue. When accepted, attach the verification report to the PR body / self-review note.
- Then run [`review-the-docs`](../review-the-docs/SKILL.md) local self-review (lint/build/classify).
- Then run [`review-the-docs`](../review-the-docs/SKILL.md) local self-review (build/classify).
- Hand off to [`create-pull-request`](https://github.com/supabase/docs-agent-skills/blob/main/.claude/skills/create-pull-request/SKILL.md) (and [`work-linear-issue`](https://github.com/supabase/docs-agent-skills/blob/main/.claude/skills/work-linear-issue/SKILL.md) if the ticket needs a full worktree+PR flow) for the actual PR mechanics. Carry the Phase 1/2 flagged-assumptions list forward explicitly into that handoff — it belongs in the PR description (e.g. a "needs review" section) so a reviewer sees it, not just as an inline comment buried in the draft.
- If the feature is UI-driven and the PR will need screenshots/GIFs, flag [`proof-it-works`](https://github.com/supabase/docs-agent-skills/blob/main/.claude/skills/proof-it-works/SKILL.md) as the next step rather than capturing evidence here.
- Before opening the PR, run [`review-the-docs`](../review-the-docs/SKILL.md) local self-review: `pnpm lint:mdx`, `pnpm build:guides-markdown` where applicable, and anchor checks per [reference/drafting-mechanics.md](reference/drafting-mechanics.md).
- Before opening the PR, run [`review-the-docs`](../review-the-docs/SKILL.md) local self-review: `pnpm build:guides-markdown` where applicable, and anchor checks per [reference/drafting-mechanics.md](reference/drafting-mechanics.md).
## Additional resources
@@ -29,18 +29,15 @@ independent of its wording, pin it with a custom anchor, for example
From `apps/docs`:
```bash
pnpm lint:mdx
pnpm build:guides-markdown
```
`pnpm lint:mdx` covers all content under `apps/docs/content`, including
troubleshooting entries. `pnpm build:guides-markdown` only applies to guides,
explainers, and tutorials.
`pnpm build:guides-markdown` only applies to guides, explainers, and tutorials.
From the repository root, run `pnpm format` to apply Prettier to changed MDX
files. This enforces repo-wide formatting rules, including lowercase SQL
keyword casing in code samples.
Treat `supa-mdx-lint` replacements as suggestions when context matters. Rewrite
the sentence instead of applying a replacement that changes its technical
meaning.
Check terminology against [`apps/docs/WORD_LIST.md`](../../../../apps/docs/WORD_LIST.md)
yourself. Treat its replacements as suggestions when context matters: rewrite the
sentence instead of applying one that changes its technical meaning.
@@ -1,67 +0,0 @@
name: docs_lint_comment_external
# This is a continuation of ./docs-lint-v2.yml, to write comments on external
# PRs.
#
# SECURITY:
# This workflow runs with write permissions, in the context of code from an
# external PR. This is safe because no external code is executed. The
# stringified Markdown output from the linter (downloaded as an artifact) is
# directly written as the body of a PR comment.
on:
workflow_run:
workflows: [docs_lint]
types:
- completed
permissions:
pull-requests: write
jobs:
comment_on_pr:
runs-on: blacksmith-4vcpu-ubuntu-2404
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'failure'
steps:
- id: download_artifact
name: 'Download artifact'
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: ${{ github.event.workflow_run.id }}
});
const matchingArtifact = artifacts?.data?.artifacts?.find(
(artifact) => artifact.name == 'lint_results'
);
if (matchingArtifact) {
core.setOutput('contains_results', 'true')
const download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchingArtifact.id,
archive_format: 'zip',
});
const fs = require('fs');
fs.writeFileSync('${{ github.workspace }}/lint_results.zip', Buffer.from(download.data));
}
- id: unzip_results
name: Unzip results file
if: steps.download_artifact.outputs.contains_results == 'true'
run: unzip lint_results.zip
- name: 'Comment on PR'
if: steps.download_artifact.outputs.contains_results == 'true'
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const fs = require('fs');
const prNumber = Number(fs.readFileSync('./pr_number.txt'));
const lintResults = fs.readFileSync('./lint_results.txt', 'utf8');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: lintResults
});
@@ -1,62 +0,0 @@
name: '[Docs] Lint v2 (scheduled)'
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
env:
CARGO_NET_GIT_FETCH_WITH_CLI: true
permissions:
contents: write
pull-requests: write
jobs:
lint-all:
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
persist-credentials: true
sparse-checkout: |
supa-mdx-lint.config.toml
supa-mdx-lint
apps/docs/content
- name: cache cargo
id: cache-cargo
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
key: da6838d8d6898f28ec9ab432353b2707db9df8f5
- name: install linter
if: steps.cache-cargo.outputs.cache-hit != 'true'
run: cargo install --locked --git https://github.com/supabase-community/supa-mdx-lint --rev da6838d8d6898f28ec9ab432353b2707db9df8f5
- name: run linter
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
supa-mdx-lint apps/docs/content || {
echo "Linter failed, attempting to fix errors..."
git config --global user.name 'github-docs-bot'
git config --global user.email 'github-docs-bot@supabase.com'
BRANCH_NAME="bot/docs-lint-fixes"
EXISTING_BRANCH=$(git ls-remote --heads origin $BRANCH_NAME)
if [[ -n "$EXISTING_BRANCH" ]]; then
git push origin --delete $BRANCH_NAME
fi
git checkout -b $BRANCH_NAME
supa-mdx-lint apps/docs/content --fix || FIX_FAILED=1
git add .
git commit -m '[bot] fix lint errors' || true
git push origin $BRANCH_NAME
gh pr create --title '[bot] fix lint errors' --body 'This PR fixes lint errors in the documentation.' --head $BRANCH_NAME
if [ "${FIX_FAILED:-0}" -eq 1 ]; then
echo "Fix did not correct all errors."
exit 1
fi
}
-108
View File
@@ -1,108 +0,0 @@
name: docs_lint
# Runs the docs linter on PRs that edit docs content.
# There are two branches of this workflow for internal and external PRs, due
# to the security design of GitHub Actions.
#
# Internal PRs:
# Have write permissions, so comments are written directly by reviewdog.
#
# External PRs:
# Have read-only permissions, so lint results are uploaded as an artifact, to
# be written to the PR in a subsequent workflow_run action that has write
# permissions. See ./docs/lint-v2-comment.yml.
#
# See https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/
on:
pull_request:
env:
CARGO_NET_GIT_FETCH_WITH_CLI: true
permissions:
pull-requests: write
jobs:
supa-mdx-lint:
name: supa-mdx-lint
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
persist-credentials: false
sparse-checkout: |
supa-mdx-lint.config.toml
supa-mdx-lint
apps/docs/content
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: filter
with:
filters: |
docs:
- 'apps/docs/content/**'
- 'supa-mdx-lint/**'
- 'supa-mdx-lint.config.toml'
- name: cache cargo
id: cache-cargo
if: steps.filter.outputs.docs == 'true'
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
key: da6838d8d6898f28ec9ab432353b2707db9df8f5
- name: install linter
if: steps.filter.outputs.docs == 'true' && steps.cache-cargo.outputs.cache-hit != 'true'
run: cargo install --locked --git https://github.com/supabase-community/supa-mdx-lint --rev da6838d8d6898f28ec9ab432353b2707db9df8f5
- name: install reviewdog
if: steps.filter.outputs.docs == 'true'
uses: reviewdog/action-setup@3f401fe1d58fe77e10d665ab713057375e39b887 # v1.3.0
with:
reviewdog_version: v0.20.2
- name: run linter (internal)
if: steps.filter.outputs.docs == 'true' && github.event.pull_request.head.repo.full_name == github.repository
env:
BASE_REF: ${{ github.base_ref }}
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -o pipefail
git diff --name-only "origin/$BASE_REF" HEAD \
| { grep -E "^apps/docs/content/" || test $? = 1; } \
| xargs -r supa-mdx-lint --format rdf \
| reviewdog -f=rdjsonl -reporter=github-pr-review -tee
- id: external_lint
name: run linter (external)
if: steps.filter.outputs.docs == 'true' && github.event.pull_request.head.repo.full_name != github.repository
env:
BASE_REF: ${{ github.base_ref }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
set -o pipefail
run_lints() {
git diff --name-only "origin/$BASE_REF" HEAD \
| { grep -E "^apps/docs/content/" || test $? = 1; } \
| xargs -rx -n 1000000000 supa-mdx-lint --format markdown
}
set +e
LINT_RESULTS=$(run_lints)
LINT_EXIT_CODE=$?
set -e
echo "LINT_EXIT_CODE=$LINT_EXIT_CODE" >> $GITHUB_OUTPUT
if [[ $LINT_EXIT_CODE -ne 0 ]]; then
mkdir -p ./__github_actions__pr
echo "${{ github.event.number }}" > ./__github_actions__pr/pr_number.txt
echo "$LINT_RESULTS" > ./__github_actions__pr/lint_results.txt
fi
- name: save results as artifact (external)
if: steps.filter.outputs.docs == 'true' && github.event.pull_request.head.repo.full_name != github.repository && steps.external_lint.outputs.LINT_EXIT_CODE != 0
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: lint_results
path: __github_actions__pr/
- name: fail if linter fails (external)
if: steps.filter.outputs.docs == 'true' && github.event.pull_request.head.repo.full_name != github.repository && steps.external_lint.outputs.LINT_EXIT_CODE != 0
run: exit 1
-1
View File
@@ -24,4 +24,3 @@ pnpm run -F docs test:local:unwatch
- Always reset the local DB before running docs tests to avoid state leakage.
- Prefer `test:local:unwatch` for non-watch CI-like runs. Append a path to run a single file: `pnpm run -F docs test:local:unwatch internals/internal-links.test.ts`.
- `pnpm test` (from `apps/docs`) wraps `test:local` in `supabase start` / `supabase stop`, but does not reset the DB and runs in watch mode, so it is not a substitute for the sequence above.
- MDX content lint is `pnpm lint:mdx` (from `apps/docs`); it lints the whole `content/` tree and takes no path arguments.
+1 -1
View File
@@ -559,7 +559,7 @@ That said, a few rules help keep the docs concise, consistent, and clear:
Use American English. If in doubt, consult the [Merriam-Webster dictionary](https://www.merriam-webster.com/).
Follow the [Supabase documentation word list](./WORD_LIST.md) for preferred spelling, capitalization, and usage. The word list includes the terminology rules checked by `supa-mdx-lint`. Run `pnpm lint:mdx` in `apps/docs` to check your changes.
Follow the [Supabase documentation word list](./WORD_LIST.md) for preferred spelling, capitalization, and usage. No tool checks terminology, so check your own prose against the list, or let `/edit-the-docs` do it.
## Search
+46 -55
View File
@@ -11,10 +11,8 @@ as code or UI text as appropriate.
The `/write-the-docs` and `/edit-the-docs` agent skills apply this list as you draft.
Many unambiguous rules in this list are checked by `supa-mdx-lint`. Run
`pnpm lint:mdx` from `apps/docs` after editing MDX. A lint warning still requires
judgment: rewrite the sentence instead of applying a replacement that changes its
meaning.
Every rule here still requires judgment: rewrite the sentence instead of applying a
replacement that changes its meaning.
## Numbers and symbols
@@ -41,8 +39,6 @@ abbreviations such as API, CPU, HTML, HTTP, or SQL unless the audience needs it.
Use `for example` instead of `e.g.` when practical. If space is constrained, write
`e.g.` with both periods. Use `that is` instead of `i.e.`.
The linter warns about malformed forms of `e.g.` and about `i.e.`.
### abort
Use _stop_, _exit_, _cancel_, or _end_ in general prose. Use `abort` when it is the
@@ -77,7 +73,7 @@ action instead of using either term as a verb.
- **Recommended**: Add the IP address to the allowlist.
- **Not recommended**: Allowlist the IP address.
Don't use _blacklist_ or _whitelist_. The linter reports these terms as errors.
Don't use _blacklist_ or _whitelist_.
When a literal code item contains one of them, format the item as code and explain
what it does.
@@ -197,7 +193,7 @@ In API documentation, a _client_ is usually an app that sends requests. Don't us
_client_ as an abbreviation for _client library_ when that could be ambiguous.
Use _concurrent connections_, not _concurrent clients_, when discussing database
connections. The linter checks this usage.
connections.
### codebase
@@ -293,8 +289,8 @@ context-appropriate term.
### easy, quick, and simple
Avoid claiming that a task is _easy_, _quick_, or _simple_. These words can be
subjective and usually add no information. The linter warns about _easy_,
_easily_, _quickly_, _simple_, and _simply_.
subjective and usually add no information. Don't use _easy_, _easily_, _quickly_,
_simple_, or _simply_.
### email
@@ -352,7 +348,7 @@ Users _fill in_ individual fields and _fill out_ an entire form.
### first person
Address the reader as _you_. Don't use singular first person (_I_, _me_, _my_, or
_mine_); the linter reports it as an error.
_mine_).
Use _we_ only when it clearly refers to Supabase, not when it means the writer and
reader together.
@@ -417,8 +413,7 @@ operation also performs substantial processing.
### in order to
Use _to_ unless _in order to_ is necessary to prevent ambiguity. The linter warns
about _in order to_.
Use _to_ unless _in order to_ is necessary to prevent ambiguity.
### inline
@@ -433,7 +428,7 @@ Use lowercase _internet_ except at the beginning of a sentence.
### just
Remove _just_ when it is filler. If it means _only_ or _previously_, use the more
specific word. The linter warns about _just_.
specific word.
## K
@@ -467,7 +462,7 @@ specific product state instead.
### leverage
Use _use_ or a more specific verb. The linter warns about _leverage_.
Use _use_ or a more specific verb instead of _leverage_.
### lifecycle
@@ -482,8 +477,7 @@ Don't use _login_ or _log in_ in prose. Use _sign in_. See
### marketing language
Describe measurable behavior instead of making promotional claims. The linter
warns about:
Describe measurable behavior instead of making promotional claims. Don't use:
- _best in class_ and _best-in-class_
- _cutting edge_ and _cutting-edge_
@@ -562,8 +556,7 @@ Write _OAuth 2.0_, not _OAuth2_, _OAuth 2_, or _Oauth_.
### obviously and of course
Remove these phrases. They can sound dismissive and don't help the reader. The
linter warns about both.
Remove these phrases. They can sound dismissive and don't help the reader.
### once
@@ -596,7 +589,7 @@ Use _plain text_ in general contexts. Use _plaintext_ in cryptography.
Don't use _please_ in normal instructions. Use it only when asking permission,
apologizing for an inconvenience, or requesting an action that primarily benefits
Supabase. The linter warns about _please_.
Supabase.
### plugin
@@ -609,17 +602,16 @@ _popup_ or _pop-up_ as a generic noun.
### Postgres
Use _Postgres_, not _PostgreSQL_, outside code and literal third-party names. The
linter checks this usage.
Use _Postgres_, not _PostgreSQL_, outside code and literal third-party names.
### powered by
Prefer _with_, _by_, or _through_, depending on the relationship. The linter warns
about _powered by_.
Don't use _powered by_. Prefer _with_, _by_, or _through_, depending on the
relationship.
### prior to and subsequent to
Use _before_ and _after_. The linter checks both phrases.
Use _before_ and _after_.
## R
@@ -690,12 +682,12 @@ established feature names such as _social login_.
### singular they
Use _they_, _them_, and _their_ as gender-neutral singular pronouns. Don't use
_s/he_, _he/she_, _(s)he_, or _him/her_. The linter reports these forms as errors.
_s/he_, _he/she_, _(s)he_, or _him/her_.
### slang abbreviations
Don't use internet slang in documentation. The linter warns about _tl;dr_, _ymmv_,
_rtfm_, _imo_, and _fwiw_.
Don't use internet slang in documentation, such as _tl;dr_, _ymmv_, _rtfm_, _imo_,
or _fwiw_.
### spin up
@@ -792,14 +784,14 @@ the reader is building or administering.
### utilize
Use _use_. Use _utilization_ only when referring to the measured proportion of a
resource in use. The linter warns about forms of _utilize_ and _utilise_.
Use _use_, not _utilize_ or _utilise_. Use _utilization_ only when referring to the
measured proportion of a resource in use.
## V
### vague verbs
Describe the concrete action. The linter suggests:
Describe the concrete action:
- _view and resolve errors_ instead of _handle errors_
- _create, edit, or delete tables_ instead of _manage tables_
@@ -840,7 +832,7 @@ _We_ is acceptable when it unambiguously means Supabase.
### while
Use _while_ for events that occur at the same time. Use _although_ or _whereas_
for contrast. Use _while_, not _whilst_; the linter checks _whilst_.
for contrast. Use _while_, not _whilst_.
### will and would
@@ -861,50 +853,49 @@ scope on first use.
Address the reader as _you_. Use _user_ only for a person who uses the software
that the reader is developing or administering.
## Lint-enforced phrase groups
## Phrase groups
The alphabetical entries explain the intent behind the rules. This section mirrors
the exact terminology checks configured in
`supa-mdx-lint/Rule004ExcludeWords`. Update this section when those rules change.
The alphabetical entries explain the intent behind each rule. This section collects
the full term lists in one place, grouped by the problem they cause.
### Filler
The linter warns about _actually_, _easily_, _easy_, _just_, _let's_,
_obviously_, _of course_, _please_, _quickly_, _simple_, _simply_, and
_that's it_. Remove the term or state the intended meaning directly.
Don't use _actually_, _easily_, _easy_, _just_, _let's_, _obviously_,
_of course_, _please_, _quickly_, _simple_, _simply_, or _that's it_. Remove the term or state the intended meaning directly.
_please_ is the exception: keep it when asking permission, apologizing for an
inconvenience, or requesting an action that primarily benefits Supabase.
### Marketing language
The linter warns about _best in class_, _best-in-class_, _cutting edge_,
Don't use _best in class_, _best-in-class_, _cutting edge_,
_cutting-edge_, _effortlessly_, _game changer_, _game-changer_, _hassle free_,
_hassle-free_, _powerful_, and _seamlessly_. Describe specific behavior or
_hassle-free_, _powerful_, or _seamlessly_. Describe specific behavior or
measurable results instead.
### Vague verbs
The linter suggests _view and resolve errors_ for _handle errors_, _create, edit,
or delete tables_ for _manage tables_, and _query and update data_ for _work with
data_. Use a different precise replacement when the suggestion doesn't match the
operation.
Use _view and resolve errors_ for _handle errors_, _create, edit, or delete tables_
for _manage tables_, and _query and update data_ for _work with data_. Use a
different precise replacement when none of these match the operation.
### Apologies
The linter warns about _oops_ and _sorry_. State what happened directly. Apologize
Don't use _oops_ or _sorry_. State what happened directly. Apologize
only when an apology is genuinely useful to the reader.
### First person
The linter reports _I_, _I'm_, _me_, _my_, and _mine_ as errors. Address the
Don't use _I_, _I'm_, _me_, _my_, or _mine_. Address the
reader as _you_ and use an explicit noun for other actors.
### Gender-neutral pronouns
The linter reports _s/he_, _he/she_, _(s)he_, and _him/her_ as errors. Use the
Don't use _s/he_, _he/she_, _(s)he_, or _him/her_. Use the
singular _they_ or rewrite the sentence.
### Inclusive language
The linter reports these terms as errors:
Don't use these terms:
- _mankind_: use _humankind_ or _people_
- _manmade_: use _manufactured_, _artificial_, or _synthetic_
@@ -914,18 +905,18 @@ The linter reports these terms as errors:
### Abbreviations
The linter corrects _eg._ and _eg_ to _e.g._. It replaces _i.e._, _ie._, and
Write _e.g._ with both periods, not _eg._ or _eg_. Replace _i.e._, _ie._, and
_ie_ with _that is_. Prefer _for example_ and _that is_ in prose when space
allows.
### Powered by
The linter warns about _powered by_. Use _with_, _by_, or _through_, depending on
the relationship.
Don't use _powered by_. Use _with_, _by_, or _through_, depending on the
relationship.
### Preferred usage
The linter suggests:
Use:
- _Postgres_ for _PostgreSQL_
- _concurrent connections_ for _concurrent clients_
@@ -935,7 +926,7 @@ The linter suggests:
### Direct, concise language
The linter warns about these phrases:
Don't use these phrases:
- _aforementioned_: name the item
- _amongst_: use _among_
@@ -950,7 +941,7 @@ The linter warns about these phrases:
### Internet slang
The linter warns about _tl;dr_, _ymmv_, _rtfm_, _imo_, and _fwiw_. Write out the
Don't use _tl;dr_, _ymmv_, _rtfm_, _imo_, or _fwiw_. Write out the
meaning or remove the aside.
## Attribution
@@ -644,8 +644,6 @@ Both of these triggers use the same `util.queue_embeddings` function that will q
Note that the update trigger only fires when the `title` or `content` columns are updated. This is to avoid unnecessary updates to the embedding column when other columns are updated. Make sure that these columns match the columns used in the `embedding_input` function.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### (Optional) Clearing embeddings on update
Note that our trigger will enqueue new embedding jobs when content is updated, but it will not clear any existing embeddings. This means that an embedding can be temporarily out of sync with the content until the new embedding is generated and updated.
-1
View File
@@ -20,7 +20,6 @@ The following example uses text embeddings. Given three phrases:
1. "The cat chases the mouse"
2. "The kitten hunts rodents"
{/* supa-mdx-lint-disable-next-line Rule004ExcludeWords */}
3. "I like ham sandwiches"
Your job is to group phrases with similar meaning. If you are a human, this should be obvious. Phrases 1 and 2 are almost identical, while phrase 3 has a completely different meaning.
@@ -229,8 +229,6 @@ order by document_sections.embedding <#> embedding;
<Admonition type="caution">
{/* supa-mdx-lint-disable-next-line Rule004ExcludeWords */}
You might be tempted to discard RLS completely and filter by user within the `where` clause. Though this will work, we recommend RLS as a general best practice since RLS is always applied even as new queries and application logic is introduced in the future.
</Admonition>
@@ -206,8 +206,6 @@ As your database scales, you will need an index on your vector columns to mainta
For larger datasets, choosing and tuning the right index is critical for maintaining fast and accurate semantic search.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
## pgvector index tuning
When working with embedding datasets at scale (100k+ rows), index selection and tuning can significantly impact query latency and accuracy.
@@ -18,8 +18,6 @@ Supabase provides client libraries for the REST and Realtime APIs. Some librarie
## Community libraries
{/* supa-mdx-lint-disable Rule003Spelling */}
| `Language` | `Source Code` | `Documentation` |
| ----------------------- | -------------------------------------------------------------------------------- | ---------------------------------------------------- |
| C# | [supabase-csharp](https://github.com/supabase-community/supabase-csharp) | [Docs](/docs/reference/csharp/introduction) |
@@ -3,8 +3,6 @@ title: A DESCRIPTIVE TITLE
subtitle: A DESCRIPTIVE SUBTITLE
---
{/* supa-mdx-lint-disable */}
{/* Use this template to document Auth Flows. These should be how-to guides, walking the reader through the process of (1) enabling the feature and (2) triggering the flow from their code. */}
A brief description of what this flow does. Don't get into details: if the concepts require a lot of explanation, make a separate page under Concepts.
@@ -148,8 +148,6 @@ var didSendMagicLink = await supabase.Auth.SendMagicLink("valid.email@supabase.i
</$Show>
</Tabs>
{/* supa-mdx-lint-disable-next-line Rule004ExcludeWords */}
That's it for the implicit flow.
If you're using PKCE flow, edit the Magic Link [email template](/docs/guides/auth/auth-email-templates) to send a token hash:
@@ -96,8 +96,6 @@ All exceptions originating from the `supabase.Auth` namespace of the C# client l
Below are the most common HTTP status codes you might encounter, along with their meanings in the context of Supabase Auth:
{/* supa-mdx-lint-disable Rule001HeadingCase */}
### [403 Forbidden](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403)
Sent out in rare situations where a certain Auth feature is not available for the user, and you as the developer are not checking a precondition whether that API is available for the user.
@@ -118,8 +116,6 @@ Indicate that the Auth server's service is degraded. Most often it points to iss
Sent out when a feature is not enabled on the Auth server, and you are trying to use an API which requires it.
{/* supa-mdx-lint-enable Rule001HeadingCase */}
## Auth error codes table
The following table provides a comprehensive list of error codes you may encounter when working with Supabase Auth. Each error code is associated with a specific issue and includes a description to help you understand and resolve the problem efficiently.
+3 -4
View File
@@ -35,7 +35,6 @@ Registering a passkey requires an existing, confirmed, non-anonymous user. Sign-
### Dashboard
Open the [Passkeys settings](/dashboard/project/_/auth/passkeys) from the **Authentication → Passkeys** section of the Dashboard, turn on **Enable Passkey authentication**, and fill in the WebAuthn [relying party](https://www.w3.org/TR/webauthn-3/#relying-party) details:
{/* supa-mdx-lint-disable-next-line Rule004ExcludeWords */}
- **Relying Party Display Name**: a human-readable name for your application shown during the passkey prompt (for example, "My App").
- **Relying Party ID**: the bare domain name for your application (for example, "example.com"). Do not include a scheme, port, or path. This determines which passkeys can be used.
@@ -403,7 +402,7 @@ let response = try await supabase.auth.verifyPasskeyAuthentication(
The `options` field returned from the start methods matches the [WebAuthn `PublicKeyCredentialCreationOptions`](https://www.w3.org/TR/webauthn-3/#dictdef-publickeycredentialcreationoptions) and [`PublicKeyCredentialRequestOptions`](https://www.w3.org/TR/webauthn-3/#dictdef-publickeycredentialrequestoptions) shapes (with `ArrayBuffer` fields encoded as base64url).
See the `auth.passkey` reference ([JavaScript](/docs/reference/javascript/auth-passkey-api) · [Dart](/docs/reference/dart/auth-passkey-api) · [Swift](/docs/reference/swift/auth-passkey-api)) for the full API.
See the `auth.passkey` reference ([JavaScript](/docs/reference/javascript/auth-passkey-list) · [Dart](/docs/reference/dart/auth-passkey-list) · [Swift](/docs/reference/swift/auth-passkey-api)) for the full API.
## Manage passkeys
@@ -474,7 +473,7 @@ try await supabase.auth.deletePasskey(id: passkeys.first!.id)
`friendlyName` is limited to 120 characters. `lastUsedAt` is updated each time the passkey is used to sign in.
See the `auth.passkey` reference ([JavaScript](/docs/reference/javascript/auth-passkey-api) · [Dart](/docs/reference/dart/auth-passkey-api) · [Swift](/docs/reference/swift/auth-passkey-api)) for the full API.
See the `auth.passkey` reference ([JavaScript](/docs/reference/javascript/auth-passkey-list) · [Dart](/docs/reference/dart/auth-passkey-list) · [Swift](/docs/reference/swift/auth-passkey-api)) for the full API.
## Admin API
@@ -520,7 +519,7 @@ await supabase.auth.admin.passkey.deletePasskey(
</TabPanel>
</Tabs>
See the `auth.admin.passkey` reference ([JavaScript](/docs/reference/javascript/auth-admin-passkey-api) · [Dart](/docs/reference/dart/auth-admin-passkey-api)) for the full API. The Swift SDK does not expose admin passkey methods.
The Swift SDK does not expose admin passkey methods.
## Error codes
@@ -26,8 +26,6 @@ To maintain the session, these tokens must be stored in a storage medium securel
## Frequently asked questions
{/* supa-mdx-lint-disable Rule004ExcludeWords */}
### No session on the server side with Next.js route prefetching?
When you use route prefetching in Next.js using `<Link href="/...">` components or the `Router.push()` APIs can send server-side requests before the browser processes the access and refresh tokens. This means that those requests may not have any cookies set and your server code will render unauthenticated content.
@@ -38,8 +36,6 @@ To improve experience for your users, we recommend redirecting users to one spec
This is not necessary. Both the access token and refresh token are designed to be passed around to different components in your application. The browser-based side of your application needs access to the refresh token to properly maintain a browser session anyway.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### My server is getting invalid refresh token errors. What's going on?
It is likely that the refresh token sent from the browser to your server is stale. Make sure the `onAuthStateChange` listener callback is free of bugs and is registered relatively early in your application's lifetime
@@ -135,7 +135,6 @@ By default, Supabase Auth uses the _common_ Microsoft tenant (`https://login.mic
If your app is registered as _Personal Microsoft accounts only_ for the _Supported account types_ set Microsoft tenant to _consumers_ (`https://login.microsoftonline.com/consumers`).
{/* supa-mdx-lint-disable-next-line Rule004ExcludeWords */}
If your app is registered as _My organization only_ for the _Supported account types_ you may want to configure Supabase Auth with the organization's tenant URL. This will use the tenant's authorization flows instead, and will limit access at the Supabase Auth level to Microsoft accounts arising from only the specified tenant.
Configure this by storing a value under _Azure Tenant URL_ in the Supabase Auth provider configuration page for Azure that has the following format `https://login.microsoftonline.com/<tenant-id>`.
@@ -17,7 +17,6 @@ Setting up Notion sign-in for your application consists of 3 parts:
## Create your notion integration
- Go to [developers.notion.com](https://developers.notion.com/).
{/* supa-mdx-lint-disable-next-line Rule004ExcludeWords */}
- Click "View my integrations" and sign in.
![notion.so](/docs/img/guides/auth-notion/notion.png)
-2
View File
@@ -86,8 +86,6 @@ Inviting a user is an admin action, so it must be performed from a trusted serve
2. Click **Add user** and select **Send invitation**.
3. Enter the user's email address and click **Invite user**.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Using the Auth Admin API
Call [`inviteUserByEmail()`](/docs/reference/javascript/auth-admin-inviteuserbyemail) from the SDK's Auth Admin API in a server-side environment. This is part of Supabase Auth (accessed via `supabase.auth.admin` with your project's [secret key](/docs/guides/getting-started/api-keys)), and is distinct from the [Management API](/docs/reference/api/introduction) used to configure your project. You can optionally attach custom `user_metadata` and a redirect URL for the invite link.
@@ -88,16 +88,12 @@ You can insert geographical data through SQL or through our API.
<h4>Restaurants</h4>
{/* supa-mdx-lint-disable Rule003Spelling */}
| id | name | location |
| --- | ----------- | -------------------------------- |
| 1 | Supa Burger | lat: 40.807416, long: -73.946823 |
| 2 | Supa Pizza | lat: 40.807475, long: -73.94581 |
| 3 | Supa Taco | lat: 40.80629, long: -73.945826 |
{/* supa-mdx-lint-enable Rule003Spelling */}
</TabPanel>
<TabPanel id="sql" label="SQL">
@@ -21,8 +21,6 @@ For this guide we'll use the following example data:
>
<TabPanel id="data" label="Data">
{/* supa-mdx-lint-disable Rule003Spelling */}
| id | title | author | description |
| --- | ----------------------------------- | ---------------------- | ------------------------------------------------------------------ |
| 1 | The Poky Little Puppy | Janette Sebring Lowrey | Puppy is slower than other, bigger animals. |
@@ -31,8 +29,6 @@ For this guide we'll use the following example data:
| 4 | Green Eggs and Ham | Dr. Seuss | Sam has changing food preferences and eats unusually colored food. |
| 5 | Harry Potter and the Goblet of Fire | J.K. Rowling | Fourth year of school starts, big drama ensues. |
{/* supa-mdx-lint-enable Rule003Spelling */}
</TabPanel>
<TabPanel id="sql" label="SQL">
@@ -357,15 +353,11 @@ var result = await supabase
<TabPanel id="data" label="Data">
{/* supa-mdx-lint-disable Rule003Spelling */}
| id | title | author | description |
| --- | ----------------------------------- | ----------------- | ----------------------------------------------- |
| 3 | Tootle | Gertrude Crampton | Little toy train has big dreams. |
| 5 | Harry Potter and the Goblet of Fire | J.K. Rowling | Fourth year of school starts, big drama ensues. |
{/* supa-mdx-lint-enable Rule003Spelling */}
</TabPanel>
</Tabs>
@@ -502,15 +494,11 @@ var result = await supabase
</$Show>
<TabPanel id="data" label="Data">
{/* supa-mdx-lint-disable Rule003Spelling */}
| id | title | author | description |
| --- | --------------------- | ---------------------- | ------------------------------------------- |
| 1 | The Poky Little Puppy | Janette Sebring Lowrey | Puppy is slower than other, bigger animals. |
| 3 | Tootle | Gertrude Crampton | Little toy train has big dreams. |
{/* supa-mdx-lint-enable Rule003Spelling */}
</TabPanel>
</Tabs>
@@ -609,14 +597,10 @@ var result = await supabase
</$Show>
<TabPanel id="data" label="Data">
{/* supa-mdx-lint-disable Rule003Spelling */}
| id | title | author | description |
| --- | ------ | ----------------- | -------------------------------- |
| 3 | Tootle | Gertrude Crampton | Little toy train has big dreams. |
{/* supa-mdx-lint-enable Rule003Spelling */}
</TabPanel>
</Tabs>
@@ -715,15 +699,11 @@ var result = await supabase
</$Show>
<TabPanel id="data" label="Data">
{/* supa-mdx-lint-disable Rule003Spelling */}
| id | title | author | description |
| --- | --------------------- | ---------------------- | ------------------------------------------- |
| 1 | The Poky Little Puppy | Janette Sebring Lowrey | Puppy is slower than other, bigger animals. |
| 3 | Tootle | Gertrude Crampton | Little toy train has big dreams. |
{/* supa-mdx-lint-enable Rule003Spelling */}
</TabPanel>
</Tabs>
@@ -1064,14 +1044,10 @@ var result = await supabase
</$Show>
<TabPanel id="data" label="Data">
{/* supa-mdx-lint-disable Rule003Spelling */}
| id | title | author | description | fts |
| --- | ------ | ----------------- | -------------------------------- | ------------------------------------------------------- |
| 3 | Tootle | Gertrude Crampton | Little toy train has big dreams. | 'big':5 'dream':6 'littl':1 'tootl':7 'toy':2 'train':3 |
{/* supa-mdx-lint-enable Rule003Spelling */}
</TabPanel>
</Tabs>
@@ -117,8 +117,6 @@ values
2. Select the `books` table in the sidebar.
3. Click **+ Insert row** and add 5 rows with the following properties:
{/* supa-mdx-lint-disable Rule003Spelling */}
| id | title | author | metadata |
| --- | ----------------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------- |
| 1 | The Poky Little Puppy | Janette Sebring Lowrey | `json {"ages":[3,6],"price":5.95,"description":"Puppy is slower than other, bigger animals."}` |
@@ -127,8 +125,6 @@ values
| 4 | Green Eggs and Ham | Dr. Seuss | `json {"ages":[4,8],"price":7.49,"description":"Sam has changing food preferences and eats unusually colored food."}` |
| 5 | Harry Potter and the Goblet of Fire | J.K. Rowling | `json {"ages":[10,99],"price":24.95,"description":"Fourth year of school starts, big drama ensues."}` |
{/* supa-mdx-lint-enable Rule003Spelling */}
</TabPanel>
<TabPanel id="js" label="JavaScript">
@@ -27,8 +27,6 @@ connection_string.../postgres?KEY1=VALUE&KEY2=VALUE&KEY3=VALUE
## Errors
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Prepared statement already exists
Supavisor in transaction mode (port 6543) does not support [prepared statements](https://www.postgresql.org/docs/current/sql-prepare.html), which Prisma will try to create in the background.
@@ -18,8 +18,6 @@ Read replicas are additional Supabase Postgres databases kept in sync with your
See [Set up read replicas](/docs/guides/platform/read-replicas).
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Pipelines
<$Partial path="pipelines-public-alpha.mdx" />
@@ -8,8 +8,6 @@ sidebar_label: 'ClickHouse'
<$Partial path="pipelines-public-alpha.mdx" />
{/* supa-mdx-lint-disable Rule003Spelling */}
The ClickHouse destination is in private alpha and available only to approved organizations. [Request access](/go/supabase-pipelines-new-destinations) before following this guide.
Replicate Postgres changes to [ClickHouse](https://clickhouse.com/) as current-state tables or an append-only history. [Choose a table engine](#choose-a-table-engine), [prepare resources](#prepare-clickhouse-resources), then [configure the destination](#configure-clickhouse-as-a-destination).
@@ -33,8 +31,6 @@ Choose the engine before creating the pipeline. Changing **Table engine** later
Updating a source primary-key value removes the old key from the current-state view and writes the row under its new key. Changing the primary-key definition is a separate [schema change](#schema-change-support).
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
## Prepare ClickHouse resources
Before creating the destination:
@@ -52,8 +48,6 @@ Keep the database otherwise empty. Pipelines manages the replicated tables and c
The default `ReplacingMergeTree` engine requires ClickHouse 23.5 or later. The `MergeTree` event-log engine does not have this minimum-version requirement.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
## Configure ClickHouse as a destination
Follow [Set up Pipelines](/docs/guides/database/replication/pipelines#setup-overview) and select **ClickHouse**. Enter these destination settings:
@@ -8,8 +8,6 @@ sidebar_label: 'DuckLake'
<$Partial path="pipelines-public-alpha.mdx" />
{/* supa-mdx-lint-disable Rule003Spelling */}
The DuckLake destination is in private alpha and available only to approved organizations. [Request access](/go/supabase-pipelines-new-destinations) before following this guide.
Replicate Postgres tables to [DuckLake](https://ducklake.select/) for current-state lakehouse queries. [Prepare resources](#understand-the-ducklake-components), [configure the destination](#choose-a-configuration-mode), then [query replicated data](#query-the-destination).
@@ -18,8 +16,6 @@ Replicate Postgres tables to [DuckLake](https://ducklake.select/) for current-st
Insert-only tables don't require a primary key or replica identity. Updates and deletes require a published Postgres row identity. See [supported replica identities](#replica-identity).
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
## Prepare DuckLake resources [#understand-the-ducklake-components]
Prepare a Postgres catalog, object storage, and a compatible query engine:
@@ -32,8 +28,6 @@ Prepare a Postgres catalog, object storage, and a compatible query engine:
You can query replicated tables, but treat them and their underlying catalog and object-storage state as read-only. Writes outside Pipelines can conflict with replication and background maintenance.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
## Configure DuckLake as a destination [#choose-a-configuration-mode]
Choose a mode below for its resource requirements and configuration steps.
@@ -8,8 +8,6 @@ sidebar_label: 'FAQ'
<$Partial path="pipelines-public-alpha.mdx" />
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
## Which plans support Pipelines?
Pipelines requires a Pro, Team, or Enterprise plan. During public alpha, availability varies by organization; an eligible plan does not guarantee access. If unavailable, request access from **Database > Replication** or contact your account manager.
@@ -22,8 +20,6 @@ BigQuery is in public alpha. ClickHouse, DuckLake, and Snowflake are in private
Yes. Distance between the source, pipeline, and destination adds network latency and can reduce throughput. Choose resources near the [managed pipeline region](/docs/guides/database/replication/pipelines#region), prioritizing the destination if you can optimize only one side.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
## What does Pipelines install in the database?
Pipelines installs objects in your project's Postgres database to track replication and support schema changes:
@@ -42,8 +38,6 @@ The `etl` schema is reserved for Pipelines. If your application already uses a s
To remove the installed objects, delete all pipelines, then [disable Pipelines](#what-happens-when-you-disable-pipelines).
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
## What does Pipelines check before creating a pipeline?
The Dashboard validates source access, replication capacity, publication tables, and destination connectivity and requirements. **Required** issues block creation; **Warnings** require review. See [creation checks](/docs/guides/database/replication/pipelines#creation-checks).
@@ -95,8 +89,6 @@ Deleting or modifying managed objects can stop replication and require a new ini
Project inactivity stops its pipelines. Start them manually after restarting the project. Downgrading to the Free Plan deletes its pipelines.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
## What happens when you disable Pipelines?
Disabling Pipelines removes its database event trigger and the entire Pipelines-managed `etl` schema, including its tables and helper functions. Your source application tables and existing destination data remain.
@@ -39,8 +39,6 @@ Follow your destination guide to prepare its resources and credentials, and chec
- [DuckLake](/docs/guides/database/replication/ducklake)
- [Snowflake](/docs/guides/database/replication/snowflake)
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Step 2: Enable Pipelines
<Admonition type="note">
@@ -175,8 +173,6 @@ A pipeline restart does not request a fresh copy of every table. Tables that com
If the main replication slot is lost and **Recreate slot** is enabled, startup rebuilds all replicated tables. Review [lost-slot recovery](/docs/guides/database/replication/pipelines-monitoring#respond-based-on-the-slot-status) for its data-loss and billing effects. To deliberately rebuild specific tables, use [Restarting tables](/docs/guides/database/replication/pipelines-monitoring#restarting-tables).
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Disabling Pipelines
Delete all pipelines first. Then open the three-dot actions menu on the Replication page and click **Disable Pipelines**.
@@ -6,8 +6,6 @@ subtitle: 'Replicate Supabase Postgres changes to Snowflake.'
sidebar_label: 'Snowflake'
---
{/* supa-mdx-lint-disable Rule003Spelling */}
<$Partial path="pipelines-public-alpha.mdx" />
The Snowflake destination is in private alpha and available only to approved organizations. [Request access](/go/supabase-pipelines-new-destinations) before following this guide.
@@ -34,8 +32,6 @@ alter table public.your_table replica identity full;
`REPLICA IDENTITY FULL` increases WAL volume, but lets Pipelines construct complete new rows when Postgres omits unchanged out-of-line TOAST values. The setting applies only to new WAL records. If retained WAL already contains an incompatible update, restart replication for the affected table after changing the setting.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
## Prepare Snowflake resources
Create a dedicated Snowflake database, schema, role, and service user for Pipelines. Keep the schema otherwise empty to avoid ownership conflicts. Use unquoted identifiers for the service user and role. Pipelines converts the account and user names to uppercase during authentication.
@@ -118,8 +114,6 @@ select current_organization_name() || '-' || current_account_name();
Enter the result as **Account ID**, for example `MYORG-MYACCOUNT`. Do not enter a full URL or dotted locator-and-region hostname. Account IDs can contain up to 63 characters. Legacy one-part account locators are also accepted. See [Snowflake account identifiers](https://docs.snowflake.com/en/user-guide/admin-account-identifier) for details.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
## Configure Snowflake as a destination
Follow [Set up Pipelines](/docs/guides/database/replication/pipelines#setup-overview) and select **Snowflake**. Enter these settings:
@@ -23,8 +23,6 @@ Tables are where you store your data.
Tables are similar to Excel spreadsheets. They contain columns and rows.
For example, this table has 3 columns named `id`, `name`, and `description`, and 4 rows of data:
{/* supa-mdx-lint-disable Rule003Spelling */}
| `id` | `name` | `description` |
| ---- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | The Phantom Menace | Two Jedi escape a hostile blockade to find allies and come across a young boy who may bring balance to the Force. |
@@ -32,8 +30,6 @@ For example, this table has 3 columns named `id`, `name`, and `description`, and
| 3 | Revenge of the Sith | As Obi-Wan pursues a new threat, Anakin acts as a double agent between the Jedi Council and Palpatine and is lured into a sinister plan to rule the galaxy. |
| 4 | Star Wars | Luke Skywalker joins forces with a Jedi Knight, a cocky pilot, a Wookiee and two droids to save the galaxy from the Empire's world-destroying battle station. |
{/* supa-mdx-lint-enable Rule003Spelling */}
There are a few important differences from a spreadsheet, but it's a good starting point if you're new to relational databases.
## Creating and managing tables
@@ -14,16 +14,12 @@ Say you have the following tables from a university database:
**`students`**
{/* supa-mdx-lint-disable Rule003Spelling */}
| id | name | type |
| --- | ---------------- | ------------- |
| 1 | Princess Leia | undergraduate |
| 2 | Yoda | graduate |
| 3 | Anakin Skywalker | graduate |
{/* supa-mdx-lint-enable Rule003Spelling */}
**`courses`**
| id | title | code |
@@ -5,8 +5,6 @@ description: 'Edge Functions can return the following error codes.'
subtitle: 'Understand the error codes returned by Edge Functions to properly debug issues and handle responses.'
---
{/* supa-mdx-lint-disable Rule001HeadingCase */}
When an Edge Function request fails, the response includes a `sb-error-code` header that identifies the specific error.
You can inspect this header in your HTTP client or application code to detect and handle errors programmatically.
@@ -410,8 +410,6 @@ To add Supabase auth per route, use the Hono adapter from `npm:@supabase/server@
---
{/* supa-mdx-lint-disable Rule001HeadingCase */}
## URL Patterns API
If you prefer not to use a web framework, you can directly use [URL Pattern API](https://developer.mozilla.org/en-US/docs/Web/API/URL_Pattern_API) within your Edge Functions to implement routing.
@@ -5,8 +5,6 @@ description: 'Edge Functions can return following status codes.'
subtitle: 'Understand HTTP status codes returned by Edge Functions to properly debug issues and handle responses.'
---
{/* supa-mdx-lint-disable Rule001HeadingCase */}
When invoking an Edge Function, the response may return a variety of HTTP status codes. The most common status codes are listed below.
<Admonition type="note">
@@ -36,7 +36,6 @@ Postgres is the core of Supabase. We do not abstract the Postgres database—you
- Official Docs: [postgresql.org/docs](https://www.postgresql.org/docs/current/index.html)
- Source code: [github.com/postgres/postgres](https://github.com/postgres/postgres) (mirror)
{/* supa-mdx-lint-disable-next-line Rule004ExcludeWords */}
- License: [PostgreSQL License](https://www.postgresql.org/about/licence/)- Language: C
### Studio (dashboard)
@@ -1,7 +1,7 @@
This file is a reference contract for framework quickstarts in this directory. It is
not a rendered page (filenames starting with `_` are excluded from the docs build
and from `supa-mdx-lint`) — it exists so every quickstart conforms to the same shape,
and so Phase 3's lint rule has a single source to check against.
not a rendered page (filenames starting with `_` are excluded from the docs build) — it
exists so every quickstart conforms to the same shape, and so a future automated check
has a single source to check against.
## Required frontmatter
@@ -148,7 +148,6 @@ light file in light mode and the base file in dark mode.
## What's deliberately not in this contract yet
- A machine-checked version of this list (Phase 3 — a `supa-mdx-lint` rule or a
vitest over the MDX AST).
- A machine-checked version of this list (Phase 3 — a vitest over the MDX AST).
- A "last verified" date, pinned framework versions, or a time-to-value label per
guide (Phase 4).
@@ -96,8 +96,6 @@ plugins {
}
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Set up Hilt for dependency injection
In the `build.gradle` (app) file, add the following:
@@ -136,8 +134,6 @@ class MainActivity : ComponentActivity() {
}
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Provide Supabase instances with Hilt
To make the app easier to test, create a `SupabaseModule.kt` file as follows:
@@ -277,8 +277,6 @@ struct UpdateProfileParams: Encodable {
Next, add a way for users to upload a profile photo. Supabase configures every project with [Storage](/docs/guides/storage) for managing large files like photos and videos.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Add `PhotosPicker`
Add support for the user to pick an image from the library and upload it.
@@ -322,8 +320,6 @@ enum TransferError: Error {
</$CodeTabs>
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### Add `PhotosPicker` to profile page
<$CodeTabs>
@@ -13,8 +13,6 @@ Using OAuth2.0 you can retrieve an access and refresh token that grant your appl
2. In the upper-right section of the page, click **Add application**.
3. Fill in the required details and click **Confirm**.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
## Show a "Connect Supabase" button
In your user interface, add a "Connect Supabase" button to kick off the OAuth flow. Follow the design guidelines outlined in our [brand assets](/brand-assets).
@@ -18,18 +18,15 @@ Without a log type selection, Logs queries **Postgres** and **API Gateway**. Sel
## Filter events
{/* supa-mdx-lint-disable Rule003Spelling */}
| Filter | Behavior |
| Filter | Behavior |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Log Type | Select API Gateway, Postgres, Auth, Storage, PostgREST, Edge Function, Realtime, or pooler events. |
| Level | Match success, warning, or error. |
| Status | Match an HTTP status or Postgres SQLSTATE. |
| Method | Match an HTTP method. |
| Pathname | Match a request path. |
| Log Type | Select API Gateway, Postgres, Auth, Storage, PostgREST, Edge Function, Realtime, or pooler events. |
| Level | Match success, warning, or error. |
| Status | Match an HTTP status or Postgres SQLSTATE. |
| Method | Match an HTTP method. |
| Pathname | Match a request path. |
| Event message | Use **iLike** or **Not iLike** for case-insensitive text matching or exclusion. Plain text matches anywhere in the message; `%` specifies a wildcard pattern. |
| User | Match the user's ID in Auth actor IDs or API Gateway JWT subjects. Other log types cannot match this filter. |
{/* supa-mdx-lint-enable Rule003Spelling */}
| User | Match the user's ID in Auth actor IDs or API Gateway JWT subjects. Other log types cannot match this filter. |
Filters other than **Event message** and **User** support **Equals** and **Not equal**. **User** supports **Equals**. Included values within a field match any selected value; exclusions remove every selected value. Filters on different fields must all match.
@@ -93,8 +93,6 @@ The following charts are available for Free and Pro plans:
| Disk usage | Free, Pro | Disk space consumption breakdown | Storage capacity planning |
| Database size | Free, Pro | Total database size and growth trends | Space consumption monitoring, including list of largest tables |
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Advanced Telemetry
{/* TODO: This is confusing and feels contradictory */}
@@ -351,8 +349,6 @@ Actions you can take:
| Implement [connection pooling](/docs/guides/database/connecting-to-postgres#choose-a-connection-method) | Optimize connection management for high direct connection usage |
| Review application code | Ensure proper connection handling and cleanup |
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Dedicated Pooler (PgBouncer) Client Connections
Available on Team and Enterprise plans.
@@ -375,8 +371,6 @@ Actions you can take:
| Implement [connection pooling](/docs/guides/database/connecting-to-postgres#choose-a-connection-method) | Optimize connection management for high direct connection usage |
| Review application code | Ensure proper connection handling and cleanup |
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Shared Pooler (Supavisor) Client Connections
Available on Team and Enterprise plans.
@@ -5,8 +5,6 @@ description: 'This documentation covers frequently asked questions around subscr
subtitle: 'This documentation covers frequently asked questions around subscription plans, payments, invoices and billing in general'
---
{/* supa-mdx-lint-disable Rule004ExcludeWords */}
## Organizations and projects
### What are organizations and projects?
@@ -61,8 +61,6 @@ height={758}
## Credit FAQ
{/* supa-mdx-lint-disable Rule004ExcludeWords */}
### Will I get an invoice for the credits purchase?
Yes, once the payment is confirmed, you will get a matching invoice that can be accessed through your [organization's invoices page](/dashboard/org/_/billing#invoices).
@@ -90,7 +90,6 @@ Use the [`domains reverify`](/docs/reference/cli/supabase-domains-reverify) comm
supabase domains reverify --project-ref abcdefghijklmnopqrst
```
{/* supa-mdx-lint-disable-next-line Rule004ExcludeWords */}
In the background, Supabase will check your DNS records and issue an SSL certificate. Supabase uses multiple Certificate Authorities (including Let's Encrypt, Google Trust Services and SSL.com) to ensure high availability. The specific issuer is chosen based on availability and this process can take up to 30 minutes.
### Prepare to activate your domain
@@ -3,7 +3,6 @@ title: 'Project Pausing'
description: 'Free project pausing behavior.'
---
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
Supabase pauses Free Plan projects that show low activity over a 7-day period to save server resources. This guide explains how pausing works, how to restore a paused project, and how to avoid pausing altogether.
<Admonition type="note">
@@ -33,20 +33,14 @@ Read Replicas run on the same Compute size as the primary database.
Read [the Manage Disk Size usage guide](/docs/guides/platform/manage-your-usage/disk-size) for details on how we calculate charges. The disk size of a Read Replica is 1.25x the size of the primary disk to account for WAL archives. With a Read Replica you go beyond your subscription plan's quota for Disk Size.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Provisioned Disk IOPS (optional)
Read Replicas inherit any additional provisioned Disk IOPS from the primary database. Read the [Manage Disk IOPS usage guide](/docs/guides/platform/manage-your-usage/disk-iops) for details on how we calculate charges.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Provisioned Disk Throughput (optional)
Read Replicas inherit any additional provisioned Disk Throughput from the primary database. Read the [Manage Disk Throughput usage guide](/docs/guides/platform/manage-your-usage/disk-throughput) for details on how we calculate charges.
{/* supa-mdx-lint-enable-next-line Rule001HeadingCase */}
### IPv4 (optional)
If the primary database has configured an IPv4 address add-on, its Read Replicas are also assigned one, with charges for each. Read the [Manage IPv4 usage guide](/docs/guides/platform/manage-your-usage/ipv4) for details on how we calculate charges.
@@ -349,8 +349,6 @@ ssl = on
listen_addresses = '*' # Or specific IP addresses
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### pg_hba.conf
```bash
@@ -61,7 +61,6 @@ Supabase will send you an AWS Resource Share containing the VPC Lattice Resource
1. Sign in to your AWS Management Console, ensure you are in the AWS region where your Supabase project is located
2. Navigate to the AWS Resource Access Manager (RAM) console
{/* supa-mdx-lint-disable-next-line Rule004ExcludeWords */}
3. Go to [Shared with me > Resource shares](https://console.aws.amazon.com/ram/home#SharedResourceShares)
4. Locate the resource share from Supabase.
- The resource share has the format `sspl-[project_ref]-[random alphanumeric string]`
@@ -70,7 +69,6 @@ Supabase will send you an AWS Resource Share containing the VPC Lattice Resource
6. Click **Accept resource share**
7. Confirm the acceptance in the dialog box
{/* supa-mdx-lint-disable-next-line Rule004ExcludeWords */}
After accepting, you'll see the resource configurations appear in your [Shared with me > Shared resources](https://console.aws.amazon.com/ram/home#SharedResources) section of the RAM console and the [PrivateLink and Lattice > Resource configurations](https://console.aws.amazon.com/vpcconsole/home#ResourceConfigs) section of the VPC console.
### Step 3: Configure security groups
@@ -150,8 +150,6 @@ You can find additional resources on replication lag in [the Google documentatio
## Troubleshooting
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### An "Init failed" status
The replica status "Init failed" in the dashboard indicates that the Read Replica has failed to deploy. Some possible scenarios as to why a Read Replica deployment may have failed are the following:
@@ -163,5 +161,3 @@ The replica status "Init failed" in the dashboard indicates that the Read Replic
- Very high active workloads combined with large (50+ GB) database sizes
It is safe to drop this failed Read Replica, and in the event of a transient issue, attempt to spin up another one. If spinning up Read Replicas for your project consistently fails, check the[status page](https://status.supabase.com) for any ongoing incidents, or [open a support ticket](/dashboard/support/new). To aid the investigation, do not bring down the recently failed Read Replica.
{/* supa-mdx-lint-enable-next-line Rule001HeadingCase */}
@@ -49,8 +49,6 @@ height={2192}
5. Usage based fee for Egress for the previous billing cycle. There is a free usage quota of 250 GB for Egress. You get charged for usage beyond 250 GB only, meaning for 2,119.47 GB. The final Egress fees are <Price price="190.75" />.
6. Usage based fee for Monthly Active Users for the previous billing cycle. There is a free usage quota of 100,000 users. With 141 users there is no charge for this line item.
{/* supa-mdx-lint-disable-next-line Rule004ExcludeWords */}
### Why is my invoice more than <Price price="25" />?
The amount due of your invoice being higher than the <Price price="25" /> subscription fee for the Pro Plan can have several reasons.
@@ -26,8 +26,6 @@ Phoenix is fast and able to handle millions of concurrent connections.
Phoenix can handle many concurrent connections because Elixir provides lightweight processes (not OS processes) to work with.
{/* supa-mdx-lint-disable-next-line Rule004ExcludeWords */}
Client-facing WebSocket servers need to handle many concurrent connections. Elixir & Phoenix let the Supabase Realtime cluster do this easily.
## Channels
@@ -491,7 +491,6 @@ Broadcast payloads can be binary (`ArrayBuffer` or `ArrayBufferView`, e.g. `Uint
</TabPanel>
</$Show>
</Tabs>
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Broadcast from the Database
@@ -11,7 +11,6 @@ To start the connection we use the WebSocket URL, which for:
- Supabase projects: `wss://<PROJECT_REF>.supabase.co/realtime/v1/websocket?apikey=<API_KEY>`
- self-hosted projects: `wss://<HOST>:<PORT>/socket/websocket?apikey=<API_KEY>`
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
As an example, using [websocat](https://github.com/vi/websocat), you would run the following command in your terminal:
```bash
@@ -114,8 +113,6 @@ The two special message types have a well defined binary format where the first
| 3 | USER_BROADCAST_PUSH | User-initiated broadcast push |
| 4 | USER_BROADCAST | User broadcast message |
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### User Broadcast Push
```
@@ -199,8 +196,6 @@ Messages for all events are encoded as text frames using JSON except with the `b
| `broadcast` | Broadcast message sent to all clients in a channel | ✅ | ✅ |
| `presence` | Presence state update sent after joining a channel | ✅ | ✅ |
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### phx_join
This is the initial message required to join a channel. The client sends this message to the server to join a specific topic and configure the features it wants to use, such as Postgres changes, Presence, and Broadcast. The payload of the `phx_join` event contains the configuration options for the channel.
@@ -285,8 +280,6 @@ Example on protocol version `2.0.0`:
]
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### phx_leave
This message is sent by the client to leave a channel. It can be used to clean up resources or stop listening for events on that channel. Payload should be empty object.
@@ -297,8 +290,6 @@ Example on protocol version `2.0.0`:
["1", "3", "realtime:avatar-stack-demo", "phx_leave", {}]
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### heartbeat
The heartbeat message should be sent at least every 25 seconds to avoid a connection timeout. Payload should be an empty object.
@@ -311,8 +302,6 @@ Example on protocol version `2.0.0`:
[null, "26", "phoenix", "heartbeat", {}]
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### access_token
Used to setup a new token to be used by Realtime for authentication and to refresh the token to prevent a private channel from closing when the token expires.
@@ -339,8 +328,6 @@ Example on protocol version `2.0.0`:
]
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### broadcast (text frame)
Used to send a broadcast event to all clients in a channel.
@@ -380,8 +367,6 @@ Example on protocol version `2.0.0`:
]
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### broadcast (binary frame)
See the [User Broadcast Push](#user-broadcast-push) section for the binary frame structure.
@@ -419,8 +404,6 @@ user-event // User Event
The payload encoding is a hint for the client to know if the payload should be treated as JSON or not.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### presence
Used to send presence metadata after joining a channel. The payload contains the presence information to be tracked by the server.
@@ -466,8 +449,6 @@ Example on protocol version `2.0.0`:
| `presence_diff` | Presence state diff update sent after a change in presence state | ⛔ | ⛔ |
| `postgres_changes` | Postgres CDC message containing changes to the database | ⛔ | ⛔ |
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### phx_close
This message is sent by the server to signal that the channel has been closed. Payload will be empty object.
@@ -478,8 +459,6 @@ Example on protocol version `2.0.0`:
["3", "3", "realtime:avatar-stack-demo", "phx_close", {}]
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### phx_error
This message is sent by the server when the channel process terminates unexpectedly. Payload will be an empty object. See [Reconnection](#reconnection) for recovery guidance.
@@ -488,8 +467,6 @@ This message is sent by the server when the channel process terminates unexpecte
["3", "3", "realtime:avatar-stack-demo", "phx_error", {}]
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### phx_reply
The server sends these messages in response to client requests that require acknowledgment.
@@ -551,8 +528,6 @@ Example on protocol version `2.0.0`:
]
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### system
The server sends system messages to inform clients about the status of their Realtime channel subscriptions. See [Channel-level system errors](#channel-level-system-errors) for the full list of messages and recovery actions.
@@ -605,12 +580,8 @@ When a channel is joined with `config.broadcast.replication_ready` set to `true`
]
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### broadcast (text frame)
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
This is the structure of broadcast events received by all clients subscribed to a channel. The `payload` field contains the event name and data that was broadcasted.
```ts
@@ -656,8 +627,6 @@ Example on protocol version `2.0.0`:
]
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### broadcast (binary frame)
See the [User Broadcast](#user-broadcast) section for the binary frame structure.
@@ -690,8 +659,6 @@ message // User Event
The metadata field is JSON encoded. The payload encoding is a hint for the client to know if the payload should be treated as JSON or not.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### postgres_changes
The server sends this message when a database change occurs in a subscribed schema and table. The payload contains the details of the change, including the schema, table, event type, and the new and old records.
@@ -779,8 +746,6 @@ When the subscription was joined with a `select` array (see [phx_join](#phx_join
]
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### presence_state
After joining, the server sends a `presence_state` message to a client with presence information. The payload field contains keys, where each key represents a client and its value is a JSON object containing information about that client. The key is defined by the client when joining the channel. If not specified, a UUID is automatically generated.
@@ -843,8 +808,6 @@ Example on protocol version `2.0.0`:
]
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
#### presence_diff
After a change to the presence state, such as a client joining or leaving, the server sends a presence_diff message to update the client's view of the presence state. The payload field contains two keys, `joins` and `leaves`, which represent clients that have joined and left, respectively. Each key is either specified by the client when joining the channel or automatically generated as a UUID.
@@ -921,8 +884,6 @@ Errors arrive on four channels:
- A `system` event on a live channel — channel-level system errors are always followed by `phx_close`, while `postgres_changes` system errors are informational and leave the channel open.
- A `phx_error` when the channel process terminates unexpectedly.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Join errors
When a `phx_join` is rejected, the `phx_reply` payload carries `response.reason` as `"<ErrorCode>: <human message>"`. The server adds a backoff delay before replying, so avoid aggressive client-side retry loops on join errors.
@@ -3,8 +3,6 @@ title: 'Realtime Reports'
description: 'Reports to help debug Realtime issues'
---
{/* supa-mdx-lint-disable Rule001HeadingCase */}
Realtime reports give insights into how your application uses Supabase Realtime, including connections, broadcast and change events, execution times, and lag.
These reports help you:
@@ -65,8 +65,6 @@ Determines the number of connections used to create [Postgres Changes](/docs/gui
Raise this value if many clients subscribe at the same time, such as after a deploy or a mass reconnect.
{/* supa-mdx-lint-disable-next-line Rule004ExcludeWords */}
### Max concurrent clients
**Type:** Number of clients · **Range:** 1 to your plan's [concurrent connections](/docs/guides/realtime/limits#limits-by-plan) limit · **Default:** your plan's limit
@@ -4,7 +4,6 @@ description: 'Copy storage objects from a managed Supabase project to a self-hos
subtitle: 'Copy storage objects from a managed Supabase project to a self-hosted instance using rclone.'
---
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
This guide walks you through copying storage objects from a managed Supabase platform project to a self-hosted instance using [rclone](https://rclone.org/) with S3-to-S3 copy.
<Admonition type="caution">
@@ -20,7 +19,6 @@ You need:
- A working self-hosted Supabase instance with the S3 protocol endpoint enabled - see [Configure S3 Storage](/docs/guides/self-hosting/self-hosted-s3#enable-the-s3-protocol-endpoint)
- Your platform project's S3 credentials - generated from the [S3 Configuration](/dashboard/project/_/storage/s3) page
- Matching buckets created on your self-hosted instance
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
- [rclone](https://rclone.org/install/) installed on the machine running the copy
## Step 1: Get platform S3 credentials
@@ -64,11 +62,8 @@ on conflict (id) do nothing;
Repeat for each bucket, setting `public` to `true` or `false` as appropriate.
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
## Step 3: Configure rclone
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
Create or edit your rclone configuration file (`~/.config/rclone/rclone.conf`):
```ini rclone.conf
@@ -141,17 +136,14 @@ Open Studio on your self-hosted instance and browse the storage buckets to confi
If you see `SignatureDoesNotMatch` when connecting to either remote:
- **Platform**: Regenerate S3 access keys from your project's Storage Settings. Ensure the endpoint URL includes `/storage/v1/s3`.
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
- **Self-hosted**: Verify that `REGION`, `S3_PROTOCOL_ACCESS_KEY_ID` and `S3_PROTOCOL_ACCESS_KEY_SECRET` in `.env` file match your rclone config.
### Bucket not found
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
If rclone reports that a bucket doesn't exist on the self-hosted side, create it first - see [Step 2](#step-2-create-buckets-on-self-hosted). The S3 protocol does not auto-create buckets on copy.
### Timeouts on large files
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
For very large files, increase rclone's timeout:
```sh
@@ -40,7 +40,6 @@ You need the following installed on your system:
- **Linux desktop**: Install [Docker Desktop](https://docs.docker.com/desktop/setup/install/linux/)
- **macOS**: Install [Docker Desktop](https://docs.docker.com/desktop/install/mac-install/)
- **Windows**: Install [Docker Desktop](https://docs.docker.com/desktop/install/windows-install/)
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
## System requirements
@@ -441,7 +440,6 @@ Everything beyond this point in the guide helps you understand how the system wo
Supabase is built from open source tools, each chosen or developed for production use.
{/* supa-mdx-lint-disable-next-line Rule004ExcludeWords */}
If the tools and communities already exist, with an MIT, Apache 2, PostgreSQL, or equivalent open source license, we will use and support that tool. If the tool doesn't exist, we build and open source it ourselves.
<Image
@@ -461,7 +459,6 @@ If the tools and communities already exist, with an MIT, Apache 2, PostgreSQL, o
- **[PostgREST](https://github.com/PostgREST/postgrest)** - Web server that turns your Postgres database directly into a RESTful API
- **[Realtime](https://github.com/supabase/realtime)** - Elixir server that listens to Postgres database changes and broadcasts them to subscribed clients
- **[Storage](https://github.com/supabase/storage)** - RESTful API for managing files in S3, with Postgres handling permissions
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
- **[imgproxy](https://github.com/imgproxy/imgproxy)** - Fast and secure image processing server
- **[postgres-meta](https://github.com/supabase/postgres-meta)** - RESTful API for managing Postgres (fetch tables, add roles, run queries)
- **[Postgres](https://github.com/supabase/postgres)** - Object-relational database with over 30 years of active development
@@ -524,7 +521,6 @@ The `generate-keys.sh` script sets the following secrets automatically. You can
- `LOGFLARE_PRIVATE_ACCESS_TOKEN`: API token for Logflare management operations. Used by Studio for administrative tasks. Never expose client-side. (Must be at least 32 characters; generate with `openssl rand -base64 24`)
- `S3_PROTOCOL_ACCESS_KEY_ID`: Access key ID (username-like) for [accessing](/docs/guides/self-hosting/self-hosted-s3) the S3 protocol endpoint in Storage. (Generate with `openssl rand -hex 16`)
- `S3_PROTOCOL_ACCESS_KEY_SECRET`: Secret key (password-like) used with S3_PROTOCOL_ACCESS_KEY_ID. (Generate with `openssl rand -hex 32`)
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
- `MINIO_ROOT_PASSWORD`: Root administrator password for the [RustFS or MinIO server](/docs/guides/self-hosting/self-hosted-s3). (Must be 8+ characters; generate with `openssl rand -hex 16`)
### Configuring Supabase services
@@ -576,14 +572,12 @@ SMTP_SENDER_NAME=your-sender-name
We recommend using [AWS SES](https://aws.amazon.com/ses/). It's affordable and reliable. Restart all services to pick up the new configuration.
### Configuring S3 Storage
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
By default, when using self-hosted Storage service, all files are stored locally on your server filesystem (via a bind mount in `docker-compose.yml`). You can connect Storage to an S3-compatible backend (AWS S3, RustFS, MinIO, Cloudflare R2), enable the S3 protocol endpoint for tools like `rclone`, or both. These are independent features.
See the [Configure S3 Storage](/docs/guides/self-hosting/self-hosted-s3) guide for detailed setup instructions.
### Using file backend in Storage on macOS
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
By default, the Storage backend uses local files via a bind mount. On macOS, Docker Desktop bind mounts have known limitations (missing xattr support, permission issues) that can prevent Storage from working correctly. Change the [bind mount](https://github.com/supabase/supabase/blob/a5f4a59e0e262394b345600e8d8a2241d6ac3b64/docker/docker-compose.yml#L391) to a named Docker volume instead.
### Configuring Supabase AI Assistant
@@ -25,7 +25,6 @@ On a fresh Postgres 17 deployment, the `pg_graphql` extension is **disabled by d
</Admonition>
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
If the new Postgres 17 container fails to start, make sure to check for an old `db-config` Docker volume. See [Postgres 17 fails to start with a leftover db-config volume](#postgres-17-fails-to-start-with-a-leftover-db-config-volume) for details.
## Upgrade an existing Postgres 15 deployment
@@ -199,8 +198,6 @@ After both phases, the upgrade script applies migrations that normally run only
## Troubleshooting
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### pg_upgrade fails with replication slot errors
`pg_upgrade` cannot proceed if there are active replication slots. Default self-hosted installs don't have any, but if you set up logical replication or have custom replication configurations, drop the slots before upgrading:
@@ -223,8 +220,6 @@ docker compose run --rm db \
chown -R postgres:postgres /var/lib/postgresql/data
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### pgsodium / Supabase Vault errors
The `db-config` named volume contains the pgsodium root encryption key at `/etc/postgresql-custom/pgsodium_root.key`. This volume is preserved during the upgrade. Never run `docker compose down -v` as this destroys named volumes and makes vault secrets unrecoverable.
@@ -253,8 +248,6 @@ sudo TMPDIR=/mnt/my-tmp bash utils/upgrade-pg17.sh
If you run out of space mid-upgrade, the safest path is to roll back and free up disk space before retrying.
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
### Postgres 17 fails to start with a leftover db-config volume
If you are starting a **fresh** Postgres 17 deployment (not using the upgrade script) and the container fails to start, the most likely cause is a leftover `db-config` volume from a previous Postgres 15 installation. Start the containers without the `-d` option or check the logs for errors about `postgresql.conf` or other configuration mismatch.
@@ -8,8 +8,6 @@ You can configure self-hosted Supabase to use the [publishable and secret API ke
## Before you begin
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
- Complete the [Docker setup guide](/docs/guides/self-hosting/docker) so that `JWT_SECRET`, `ANON_KEY`, and `SERVICE_ROLE_KEY` are set in your `.env` file. [Quick start (Linux)](/docs/guides/self-hosting/docker#quick-start-linux) handles this automatically; the manual path runs [`generate-keys.sh`](/docs/guides/self-hosting/docker#generate-keys-and-secrets).
- If you are upgrading from a legacy self-hosted Supabase environment, make sure to check the [changelog](https://github.com/supabase/supabase/blob/master/docker/CHANGELOG.md#2026-03-16) and [add/update](/docs/guides/self-hosting/updating) the following files:
- `.env.example` (merge new sections into your `.env` file)
@@ -8,8 +8,6 @@ Self-hosted Supabase uses an [Envoy](https://www.envoyproxy.io/)-based API gatew
This guide explains the architecture, configuration layout, and security posture of the Envoy gateway for operators who want to understand or customize it. It is not an Envoy tutorial - for reference on filters, routes, and clusters, see the [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/).
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
## Using the gateway
Envoy is the default API gateway and runs automatically when you start the stack - no extra configuration is required.
@@ -66,8 +66,6 @@ GOOGLE_CLIENT_ID=your-client-id
GOOGLE_SECRET=your-client-secret
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Step 3: Enable the matching lines in Docker Compose configuration
Uncomment the corresponding `GOTRUE_EXTERNAL_` lines in the `auth` service's `environment`:
@@ -407,8 +405,6 @@ After a successful OAuth sign-in, the Auth service redirects to `SITE_URL` or a
- `SITE_URL` in `.env` is set to your **application's URL**
- If your app uses a different redirect URL, add it to `ADDITIONAL_REDIRECT_URLS` (comma-separated)
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Nonce check failure on mobile (Google Sign In)
When using Google Sign In on mobile with ID tokens, nonce verification may fail because mobile SDKs don't always support the nonce flow that the Auth service expects.
@@ -40,8 +40,6 @@ SMS_TWILIO_AUTH_TOKEN=your-auth-token
SMS_TWILIO_MESSAGE_SERVICE_SID=your-message-service-sid
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Step 2: Uncomment the matching lines in Docker Compose configuration
Uncomment the `GOTRUE_SMS_*` lines in the `auth` service's `environment` block:
@@ -4,8 +4,6 @@ description: 'Set up a reverse proxy with HTTPS for self-hosted Supabase.'
subtitle: 'Set up a reverse proxy with HTTPS for self-hosted Supabase.'
---
{/* supa-mdx-lint-disable Rule004ExcludeWords */}
HTTPS is required for production self-hosted Supabase deployments. This guide covers two production approaches using a reverse proxy in front of self-hosted Supabase API gateway, plus a self-signed certificate option for development environment.
## Before you begin
@@ -135,8 +133,6 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
chgrp 65533 volumes/api/server.key
```
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
### Step 2: Configure Kong for SSL
Comment out Kong's **HTTP** port mapping in `docker-compose.yml`:
@@ -5,10 +5,8 @@ subtitle: 'Enable S3-compatible client endpoint and set up an S3 backend for sel
---
Self-hosted Supabase Storage has two independent S3-related features:
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
- **S3 protocol endpoint** - an S3-compatible API that Storage exposes at `/storage/v1/s3`. This allows standard S3 tools like `rclone` and the AWS CLI to interact with your Storage instance.
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
- **S3 backend** - where Storage keeps data. By default, files are stored on the local filesystem. You can switch to an S3-compatible service (AWS S3, MinIO, etc.) for durability, scalability, or to use existing infrastructure.
You can configure either feature independently. For example, you can enable the S3 protocol endpoint to use `rclone` while keeping the default file-based storage, or switch to an S3 backend without enabling the S3 protocol endpoint.
@@ -42,8 +40,6 @@ aws s3 ls \
s3://your-storage-bucket )
```
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
### Test with rclone
```sh
@@ -79,15 +75,10 @@ storage:
REGION: your-region
```
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
Depending on your setup, you may need to adjust these values - for example, to use a local S3-compatible service like RustFS, MinIO or a cloud provider like AWS.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
### Using RustFS
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
An override `docker-compose.rustfs.yml` can be added to enable RustFS container and provide an S3-compatible API for Storage backend:
```sh
@@ -97,19 +88,14 @@ sh run.sh start
Make sure to review the Storage section in your `.env` file for related configuration options.
{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
### Using MinIO
<Admonition type="note">
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
MinIO no longer publishes open source Docker images or maintains their open source repository. The MinIO configuration is provided for backward compatibility and uses images built by [Chainguard](https://images.chainguard.dev/directory/image/minio/overview) (`cgr.dev/chainguard/minio`). For new deployments, consider using [RustFS](#using-rustfs) instead.
</Admonition>
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
An override `docker-compose.s3.yml` can be added to enable MinIO container and provide an S3-compatible API for Storage backend:
```sh
@@ -138,7 +124,6 @@ For AWS S3, you do not need `GLOBAL_S3_ENDPOINT` or `GLOBAL_S3_FORCE_PATH_STYLE`
### S3-compatible providers
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
Use the same configuration as MinIO, replacing the endpoint, bucket name, region, and AWS credentials with the values provided by your S3-compatible provider, for example:
```yaml name=docker-compose.yml
@@ -156,8 +141,6 @@ storage:
## Verify the setup
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
- Open Studio and upload a file to a bucket. List the file using the AWS CLI or `rclone` to confirm the S3 endpoint works.
- If using an S3 backend: confirm the file appears in your S3 provider's console.
@@ -4,7 +4,6 @@ description: 'Set up SAML 2.0 Single Sign-On for self-hosted Supabase with Docke
subtitle: 'Set up SAML 2.0 Single Sign-On for self-hosted Supabase with Docker.'
---
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
SAML 2.0 SSO lets your users authenticate through an enterprise Identity Provider (IdP) such as Okta, Azure AD (Entra ID), Google Workspace, or any SAML 2.0-compliant provider. Unlike OAuth providers, SAML IdPs are not configured through environment variables - they are managed dynamically at runtime through the Auth admin API.
This guide covers the full setup: generating a signing key, enabling SAML in your Supabase instance, registering an IdP, and integrating SSO into your application.
@@ -138,21 +137,18 @@ This returns an XML document containing your SP entity ID, ACS endpoint URL, and
<Admonition type="note">
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
Add `?download=true` to the request URL to get the metadata as a downloadable XML file with a 5-year validity period - this is useful for IdPs that require a file upload instead of a URL.
</Admonition>
Key values in the metadata:
{/* supa-mdx-lint-disable Rule003Spelling */}
| Field | Value |
|---|---|
| Entity ID | `{API_EXTERNAL_URL}/sso/saml/metadata` |
| ACS URL | `{API_EXTERNAL_URL}/sso/saml/acs` |
| NameID formats | `persistent`, `emailAddress` |
| Signing certificate | Derived from your `SAML_PRIVATE_KEY` |
{/* supa-mdx-lint-enable Rule003Spelling */}
| Field | Value |
| ------------------- | -------------------------------------- |
| Entity ID | `{API_EXTERNAL_URL}/sso/saml/metadata` |
| ACS URL | `{API_EXTERNAL_URL}/sso/saml/acs` |
| NameID formats | `persistent`, `emailAddress` |
| Signing certificate | Derived from your `SAML_PRIVATE_KEY` |
## Step 6: Register an identity provider
@@ -200,7 +196,6 @@ curl -X POST 'http://<your-domain>/auth/v1/admin/sso/providers' \
<Admonition type="note">
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
When using `metadata_url`, the URL must use HTTPS. Auth validates the metadata XML format and checks that the EntityID is unique across all registered providers.
</Admonition>
@@ -224,31 +219,27 @@ The response includes the provider `id` (UUID) - save this for use in your appli
### Registration parameters reference
{/* supa-mdx-lint-disable Rule003Spelling */}
| Parameter | Required | Description |
|---|---|---|
| `type` | Yes | Must be `"saml"` |
| `metadata_url` | One of these | HTTPS URL to the IdP's SAML metadata (auto-refreshed) |
| `metadata_xml` | One of these | Raw IdP metadata XML string |
| `domains` | No | Array of email domains to associate (e.g., `["acme.com"]`). Used for domain-based SSO lookup. |
| `attribute_mapping` | No | Map SAML attributes to user claims (see [Attribute mapping](#attribute-mapping)) |
| `name_id_format` | No | Request a specific NameID format: `persistent`, `emailAddress`, `transient`, or `unspecified` |
| `resource_id` | No | A custom external identifier for the provider |
| `disabled` | No | Set to `true` to register but disable the provider |
{/* supa-mdx-lint-enable Rule003Spelling */}
| Parameter | Required | Description |
| ------------------- | ------------ | --------------------------------------------------------------------------------------------- |
| `type` | Yes | Must be `"saml"` |
| `metadata_url` | One of these | HTTPS URL to the IdP's SAML metadata (auto-refreshed) |
| `metadata_xml` | One of these | Raw IdP metadata XML string |
| `domains` | No | Array of email domains to associate (e.g., `["acme.com"]`). Used for domain-based SSO lookup. |
| `attribute_mapping` | No | Map SAML attributes to user claims (see [Attribute mapping](#attribute-mapping)) |
| `name_id_format` | No | Request a specific NameID format: `persistent`, `emailAddress`, `transient`, or `unspecified` |
| `resource_id` | No | A custom external identifier for the provider |
| `disabled` | No | Set to `true` to register but disable the provider |
## Step 8: Configure your identity provider
On the IdP side, create a new SAML application and configure it with your SP details:
{/* supa-mdx-lint-disable Rule003Spelling */}
| IdP setting | Value |
|---|---|
| SP Entity ID / Audience | `{API_EXTERNAL_URL}/sso/saml/metadata` |
| ACS URL / Reply URL | `{API_EXTERNAL_URL}/sso/saml/acs` |
| NameID format | `persistent` (recommended) or `emailAddress` |
| Signing certificate | Upload from the SP metadata XML or provide the metadata URL |
{/* supa-mdx-lint-enable Rule003Spelling */}
| IdP setting | Value |
| ----------------------- | ----------------------------------------------------------- |
| SP Entity ID / Audience | `{API_EXTERNAL_URL}/sso/saml/metadata` |
| ACS URL / Reply URL | `{API_EXTERNAL_URL}/sso/saml/acs` |
| NameID format | `persistent` (recommended) or `emailAddress` |
| Signing certificate | Upload from the SP metadata XML or provide the metadata URL |
### IdP-specific configuration
@@ -262,14 +253,12 @@ On the IdP side, create a new SAML application and configure it with your SP det
<TabPanel id="okta" label="Okta">
**Okta setup:**
{/* supa-mdx-lint-disable Rule003Spelling */}
- Create a "SAML 2.0" application
- Single Sign-On URL: `{API_EXTERNAL_URL}/sso/saml/acs`
- Audience URI (SP Entity ID): `{API_EXTERNAL_URL}/sso/saml/metadata`
- Default RelayState: leave blank
- Name ID format: `Persistent`
{/* supa-mdx-lint-enable Rule003Spelling */}
</TabPanel>
@@ -318,21 +307,17 @@ On the IdP side, create a new SAML application and configure it with your SP det
Attribute mapping lets you control how SAML assertion attributes are translated into Supabase user claims. If no mapping is provided, Auth uses sensible defaults:
**Default email detection order:**
{/* supa-mdx-lint-disable Rule003Spelling */}
1. `urn:oid:0.9.2342.19200300.100.1.3` (LDAP mail OID)
2. `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress`
3. `http://schemas.xmlsoap.org/claims/EmailAddress`
4. Attributes named `mail`, `Mail`, or `email`
5. Subject NameID (if it looks like an email address)
{/* supa-mdx-lint-enable Rule003Spelling */}
**Default user ID detection:**
{/* supa-mdx-lint-disable Rule003Spelling */}
1. `urn:oasis:names:tc:SAML:attribute:subject-id` attribute
2. Subject NameID (if format is `persistent`)
{/* supa-mdx-lint-enable Rule003Spelling */}
### Custom attribute mapping example
@@ -521,15 +506,13 @@ The response should include `app_metadata.provider: "sso:saml"` and any mapped a
## Environment variable reference
{/* supa-mdx-lint-disable Rule003Spelling */}
| Variable | Default | Description |
|---|---|---|
| `SAML_ENABLED` | `false` | Enable the SAML SSO engine |
| `SAML_PRIVATE_KEY` | - | Base64-encoded PKCS#1 RSA private key (min 2048-bit). Used to sign SAML requests and optionally decrypt assertions. |
| `SAML_ALLOW_ENCRYPTED_ASSERTIONS` | `false` | Accept encrypted SAML assertions from IdPs |
| `SAML_RELAY_STATE_VALIDITY_PERIOD` | `2m0s` | How long relay state tokens remain valid. Increase if users on slow networks time out during the IdP redirect. |
| `SAML_RATE_LIMIT_ASSERTION` | `15` | Maximum ACS requests per second. Protects against assertion replay floods. |
{/* supa-mdx-lint-enable Rule003Spelling */}
| Variable | Default | Description |
| ---------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------- |
| `SAML_ENABLED` | `false` | Enable the SAML SSO engine |
| `SAML_PRIVATE_KEY` | - | Base64-encoded PKCS#1 RSA private key (min 2048-bit). Used to sign SAML requests and optionally decrypt assertions. |
| `SAML_ALLOW_ENCRYPTED_ASSERTIONS` | `false` | Accept encrypted SAML assertions from IdPs |
| `SAML_RELAY_STATE_VALIDITY_PERIOD` | `2m0s` | How long relay state tokens remain valid. Increase if users on slow networks time out during the IdP redirect. |
| `SAML_RATE_LIMIT_ASSERTION` | `15` | Maximum ACS requests per second. Protects against assertion replay floods. |
## Troubleshooting
@@ -576,8 +559,6 @@ base64 -w 0 -i pk_rsa1.der
### User is created but attributes are missing
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
- Check your `attribute_mapping` configuration. Use the IdP's SAML assertion viewer (most IdPs have one) to see the exact attribute names being sent.
- Attribute names are matched case-insensitively against both the `Name` and `FriendlyName` fields in the assertion.
- Mapped attributes appear in `user.user_metadata`.
@@ -24,8 +24,6 @@ The most commonly used endpoints are implemented, and more will be added. Implem
### Bucket operations
{/* supa-mdx-lint-disable Rule003Spelling */}
| API Name | Feature |
| ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ✅ [ListBuckets](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html) | |
@@ -40,12 +38,8 @@ The most commonly used endpoints are implemented, and more will be added. Implem
| ❌ [PutBucketCors](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html) | ❌ Checksums:<br/> ❌ x-amz-sdk-checksum-algorithm<br/> ❌ x-amz-checksum-algorithm<br/>❌ Bucket Owner:<br/> ❌ x-amz-expected-bucket-owner |
| ❌ [PutBucketLifecycleConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html) | ❌ Checksums:<br/> ❌ x-amz-sdk-checksum-algorithm<br/> ❌ x-amz-checksum-algorithm<br/>❌ Bucket Owner:<br/> ❌ x-amz-expected-bucket-owner |
{/* supa-mdx-lint-enable Rule003Spelling */}
### Object operations
{/* supa-mdx-lint-disable Rule003Spelling */}
| API Name | Feature |
| -------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ✅ [HeadObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html) | ✅ Conditional Operations:<br/> ✅ If-Match<br/> ✅ If-Modified-Since<br/> ✅ If-None-Match<br/> ✅ If-Unmodified-Since<br/>✅ Range:<br/> ✅ Range (has no effect in HeadObject)<br/> ✅ partNumber<br/>❌ SSE-C:<br/> ❌ x-amz-server-side-encryption-customer-algorithm<br/> ❌ x-amz-server-side-encryption-customer-key<br/> ❌ x-amz-server-side-encryption-customer-key-MD5<br/>❌ Request Payer:<br/> ❌ x-amz-request-payer<br/>❌ Bucket Owner:<br/> ❌ x-amz-expected-bucket-owner |
@@ -63,5 +57,3 @@ The most commonly used endpoints are implemented, and more will be added. Implem
| ✅ [UploadPart](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) | ✅ System Metadata:<br/>❌ Content-MD5<br/>❌ SSE-C:<br/> ❌ x-amz-server-side-encryption<br/> ❌ x-amz-server-side-encryption-customer-algorithm<br/> ❌ x-amz-server-side-encryption-customer-key<br/> ❌ x-amz-server-side-encryption-customer-key-MD5<br/>❌ Request Payer:<br/> ❌ x-amz-request-payer<br/>❌ Bucket Owner:<br/> ❌ x-amz-expected-bucket-owner |
| ✅ [UploadPartCopy](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html) | ❌ Conditional Operations:<br/> ❌ x-amz-copy-source<br/> ❌ x-amz-copy-source-if-match<br/> ❌ x-amz-copy-source-if-modified-since<br/> ❌ x-amz-copy-source-if-none-match<br/> ❌ x-amz-copy-source-if-unmodified-since<br/>✅ Range:<br/> ✅ x-amz-copy-source-range<br/>❌ SSE-C:<br/> ❌ x-amz-server-side-encryption-customer-algorithm<br/> ❌ x-amz-server-side-encryption-customer-key<br/> ❌ x-amz-server-side-encryption-customer-key-MD5<br/> ❌ x-amz-copy-source-server-side-encryption-customer-algorithm<br/> ❌ x-amz-copy-source-server-side-encryption-customer-key<br/> ❌ x-amz-copy-source-server-side-encryption-customer-key-MD5<br/>❌ Request Payer:<br/> ❌ x-amz-request-payer<br/>❌ Bucket Owner:<br/> ❌ x-amz-expected-bucket-owner<br/> ❌ x-amz-source-expected-bucket-owner |
| ✅ [ListParts](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html) | Query Parameters:<br/> ✅ max-parts<br/> ✅ part-number-marker<br/>❌ Request Payer:<br/> ❌ x-amz-request-payer<br/>❌ Bucket Owner:<br/> ❌ x-amz-expected-bucket-owner |
{/* supa-mdx-lint-enable Rule003Spelling */}
@@ -110,8 +110,6 @@ However, you can also review the below **example cases** for an idea of possible
### Example cases
{/* supa-mdx-lint-disable Rule003Spelling */}
### TypeError: Undefined variables
A `TypeError` occurs when any JavaScript datatype is misused. For instance, trying to execute a number as if it were a function would cause the error:
@@ -170,8 +168,6 @@ finally {
}
```
{/* supa-mdx-lint-disable Rule003Spelling */}
### ReferenceError: Var is not defined
A `ReferenceError` occurs when one tries to reference a variable that does not exist in the code's scope. Often times caused by a typo or missing import.
@@ -224,8 +220,6 @@ catch (error) {
}
```
{/* supa-mdx-lint-disable Rule003Spelling */}
### SyntaxError: Special case - CORS violation
A `SyntaxError` error occurs when Deno's grammatical rules are violated, such as failing to close a parenthesis:
@@ -6,8 +6,6 @@ keywords = [ "channels", "useEffect", "react", "memory leak", "quota", "TooManyC
database_id = "dee93cc3-0ab1-4101-8ad4-31d8682c8844"
---
{/* supa-mdx-lint-disable Rule003Spelling */}
## What is the TooManyChannels error?
The TooManyChannels error occurs when your application tries to create more than the allowed number of Realtime channels. When you exceed this limit, you'll see an error with the code `ChannelRateLimitReached`.
@@ -16,21 +14,15 @@ This limit exists to protect both your application and Supabase servers from res
## What causes TooManyChannels errors?
{/* supa-mdx-lint-enable Rule003Spelling */}
The most common cause is accidentally creating channels without cleaning them up, especially in React applications. This happens when:
{/* supa-mdx-lint-disable Rule003Spelling */}
- Components create channels on every render without unsubscribing
- `useEffect` runs multiple times due to missing or incorrect dependencies
- Components unmount without cleaning up their channels
- Development mode in React (StrictMode) causes effects to run twice
{/* supa-mdx-lint-enable Rule003Spelling */}
Each time you call `supabase.channel('topic').subscribe()`, a new channel is created unless you properly clean it up.
{/* supa-mdx-lint-disable Rule003Spelling */}
Here's the most common mistake that might lead to TooManyChannels errors:
{/* supa-mdx-lint-enable Rule003Spelling */}
```tsx
// ❌ WRONG - Creates new channel on every render
@@ -64,8 +56,8 @@ Why this fails:
```tsx
// ✅ CORRECT - Properly manages channel lifecycle
import { useEffect } from 'react'
import { createClient } from '@supabase/supabase-js'
import { useEffect } from 'react'
// Create client outside component (singleton)
const supabase = createClient(SUPABASE_URL, SUPABASE_KEY)
@@ -189,9 +181,7 @@ console.log(channel1 === channel2) // true
### 5. Handle strict mode in development
{/* supa-mdx-lint-disable Rule003Spelling */}
React StrictMode intentionally runs effects twice in development. Your cleanup function will handle this:
{/* supa-mdx-lint-enable Rule003Spelling */}
```tsx
// This works correctly even in StrictMode
@@ -206,8 +196,6 @@ useEffect(() => {
}, [])
```
{/* supa-mdx-lint-disable Rule003Spelling */}
### 6. Clean up on unmount for dynamic channels
If you create channels based on props:
@@ -195,7 +195,6 @@ Execution Time: 0.046 ms
[Stable functions do not seem to be honored in RLS in basic form](https://github.com/orgs/supabase/discussions/9311)
[current_setting can lead to bad performance when used on RLS](https://github.com/PostgREST/postgrest-docs/issues/609#)
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
Thanks Steve Chavez and Wolfgang Walther in those threads.
### Added example of security definer function having select of a team table, comparing against a column in main table
@@ -225,8 +224,6 @@ $$ language plpgsql security definer;
Some results:
{/* supa-mdx-lint-disable Rule003Spelling */}
| Policy | Index | Main Rs | Team Rs | on 10 teams | 100 | 500 | note |
| -------------------------------- | ----- | ------- | ------- | ----------- | ----- | ----- | ------------------ |
| =ANY(user_teams()) | no | 1M | 1000 | >2Min | >2Min | >2Min | TO or killed |
@@ -235,5 +232,3 @@ Some results:
| =ANY(ARRAY(select user_teams())) | yes | 1M | 1000 | 2ms | 3 | 3 | |
| in(1,2,3...100) | no | 1M | NA | 130ms | 142 | x | baseline check |
| =ANY(ARRAY(select user_teams())) | yes | 1M | 10K | x | x | x | 24ms (on 1K teams) |
{/* supa-mdx-lint-enable Rule003Spelling */}
@@ -24,8 +24,6 @@ Whatever the reason, here's how to rotate the keys for your Supabase project.
If you haven’t migrated to asymmetric JWT signing keys:
{/* supa-mdx-lint-disable Rule004ExcludeWords */}
We recommend that you migrate to asymmetric JWT signing keys and publishable/secret API keys as it is no longer possible to rotate the legacy anon, service and JWT secrets.
You can view this [**Get Started guide**](/docs/guides/auth/signing-keys#getting-started) for steps to migrate to asymmetric JWT signing keys.
@@ -111,7 +111,6 @@ This query:
**Example Output:**
| db_role | detected_user | error_severity | event_message | identifier |
| -------- | ------------- | -------------- | -------------------------------------------------------------------------------- | ---------- |
{/* supa-mdx-lint-disable-next-line Rule003Spelling */}
| postgres | support | LOG | statement: TRUNCATE TABLE public.data; -- source: dashboard -- user: f8c2e1a9... | ... |
You can further refine your search by filtering for specific commands like `TRUNCATE` or `DELETE` where `parsed.user_name = 'postgres'`.
-2
View File
@@ -33,7 +33,6 @@
"last-changed": "tsx scripts/last-changed.ts",
"last-changed:reset": "pnpm run last-changed -- --reset",
"lint": "eslint .",
"lint:mdx": "supa-mdx-lint content --config ../../supa-mdx-lint.config.toml",
"postbuild": "pnpm run build:sitemap && ./../../scripts/upload-static-assets.sh",
"prebuild": "pnpm run codegen:graphql && pnpm run codegen:references && pnpm run codegen:examples && pnpm build:federated-content && pnpm run build:markdown && pnpm run build:gz-archive",
"predev": "pnpm run codegen:graphql && pnpm run codegen:references && pnpm run codegen:examples",
@@ -142,7 +141,6 @@
"@graphql-codegen/typescript": "4.1.6",
"@graphql-codegen/typescript-resolvers": "4.5.0",
"@redocly/cli": "^2.26.0",
"@supabase/supa-mdx-lint": "0.3.2",
"@testing-library/react": "^16.3.3",
"@types/common-tags": "^1.8.4",
"@types/estree": "1.0.5",
-2
View File
@@ -13,7 +13,6 @@
"internal:sync": "tsx ./scripts/sync-internal-content.mts",
"start": "next start",
"lint": "eslint .",
"lint:mdx": "supa-mdx-lint content --config ../../supa-mdx-lint.config.toml",
"clean": "rimraf .next .turbo tsconfig.tsbuildinfo .contentlayer .velite tsconfig.tsbuildinfo",
"typecheck": "pnpm build:content && tsc --noEmit"
},
@@ -40,7 +39,6 @@
},
"devDependencies": {
"@shikijs/compat": "^1.1.7",
"@supabase/supa-mdx-lint": "0.3.1",
"@types/react": "catalog:",
"config": "workspace:^",
"mdast-util-toc": "^6.1.1",
-2
View File
@@ -18,7 +18,6 @@
"test:headless-tools": "tsx scripts/test-headless-tools.mts",
"start": "next start",
"lint": "eslint .",
"lint:mdx": "supa-mdx-lint content --config ../../supa-mdx-lint.config.toml",
"clean": "rimraf .next .turbo tsconfig.tsbuildinfo .contentlayer .velite",
"typecheck": "run-p build:content build:markdown && next typegen && tsc --noEmit -p tsconfig.json"
},
@@ -28,7 +27,6 @@
"@react-router/fs-routes": "^7.4.0",
"@supabase-labs/y-supabase": "0.1.0",
"@supabase/postgrest-js": "catalog:",
"@supabase/supa-mdx-lint": "0.2.6-alpha",
"@supabase/vue-blocks": "workspace:*",
"@tanstack/react-query": "~5.83.0",
"@xyflow/react": "^12.10.1",
-254
View File
@@ -606,9 +606,6 @@ importers:
'@redocly/cli':
specifier: ^2.26.0
version: 2.34.0
'@supabase/supa-mdx-lint':
specifier: 0.3.2
version: 0.3.2
'@testing-library/react':
specifier: ^16.3.3
version: 16.3.3(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
@@ -860,9 +857,6 @@ importers:
'@shikijs/compat':
specifier: ^1.1.7
version: 1.6.0
'@supabase/supa-mdx-lint':
specifier: 0.3.1
version: 0.3.1
'@types/react':
specifier: 'catalog:'
version: 19.2.14
@@ -1522,9 +1516,6 @@ importers:
'@supabase/postgrest-js':
specifier: 'catalog:'
version: 2.116.0
'@supabase/supa-mdx-lint':
specifier: 0.2.6-alpha
version: 0.2.6-alpha
'@supabase/vue-blocks':
specifier: workspace:*
version: link:../../blocks/vue
@@ -8398,141 +8389,6 @@ packages:
resolution: {integrity: sha512-6/3hR6vccBP6oGM5B6RfbwZcTCKmQOodd/ZWQdsw8yJsU5zO/a//oBL6yLnmgxcjnHSrelW8rsO7hL5DPybyUQ==}
engines: {node: '>=22.0.0'}
'@supabase/supa-mdx-lint-darwin@0.2.6-alpha':
resolution: {integrity: sha512-tDyl2SWfuFb5yckD1cyd5CfmkAbvx9onaxXFrMTP/1bB/sYM3RI2BJQ7/lfZy0jcIiMvc70LroJe5EYx37yYsQ==}
engines: {node: '>=10'}
os: [darwin]
'@supabase/supa-mdx-lint-darwin@0.3.1':
resolution: {integrity: sha512-kX4cFMIP9OStV1j9zWy/wfrk5KKrn3DtBwP7y8GPHe05Y7nTfQOoqHpIKbHswJRB5OxFC3ETpI6DocQeWcrZ6Q==}
engines: {node: '>=10'}
os: [darwin]
'@supabase/supa-mdx-lint-darwin@0.3.2':
resolution: {integrity: sha512-GGG0X1DiQLldkKIw8CDFQFYqK4aLgx6DIdzhOMwZrH34ADcE+WdExVnsHqaSE4eRwKsX531Hz+iJgiybWx1TBA==}
engines: {node: '>=10'}
os: [darwin]
'@supabase/supa-mdx-lint-linux-arm64@0.2.6-alpha':
resolution: {integrity: sha512-y51H1VW4VIpsFB/ui8GEU1h15tPp9fL8p2NMDltNEUrjSYpH7hzbj+surxy/FA0JdXllpqNV+7UvDm/FIz/Klg==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux, freebsd]
'@supabase/supa-mdx-lint-linux-arm64@0.3.1':
resolution: {integrity: sha512-4zVQkqxnn+HYSbYED9egnw/nuF5/Z8pK1Kp2vmv5cNUaQvyreHZzC1opRjO11HgqBZZGMm5AybsY3lEEQ5pqpg==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux, freebsd]
'@supabase/supa-mdx-lint-linux-arm64@0.3.2':
resolution: {integrity: sha512-qRxTxZQBGc7uHVTH3mMAYilIgnZ7CvMQYeoJa5LbVhjAUmDjKwx5hTu1SoW2OyhkueMJcz887+Kynas2WO8ADw==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux, freebsd]
'@supabase/supa-mdx-lint-linux-arm@0.2.6-alpha':
resolution: {integrity: sha512-8UOMo8nRUDtaDuFjMlSjtaA6WjuZVRz5jRFFoFotm16QxA4+JMS00g6rmYl2nyt6Vjj/bCiFdS60oOWzPHFtBQ==}
engines: {node: '>=10'}
cpu: [arm]
os: [linux, freebsd]
'@supabase/supa-mdx-lint-linux-arm@0.3.1':
resolution: {integrity: sha512-fcR7oKKgrXbVHKtOLjbtPPP3fg/FxaYLnnYYVulJM4Xh+0dPFmCox1xIo7OZKbHy7pEa+GJUwSgT1WlhZLN34Q==}
engines: {node: '>=10'}
cpu: [arm]
os: [linux, freebsd]
'@supabase/supa-mdx-lint-linux-arm@0.3.2':
resolution: {integrity: sha512-KCCJ6iP6/s3SrbkvwWo/cjX6+LOp56C/mSM0NkVzaRpsc9VcN39/4gA1Ls7O2jOV/g2fnIEWfdRef6dY9ob+bA==}
engines: {node: '>=10'}
cpu: [arm]
os: [linux, freebsd]
'@supabase/supa-mdx-lint-linux-i686@0.2.6-alpha':
resolution: {integrity: sha512-Vjcn3hGNsw4V9x6RpI9S75byeqlkHbkVNPtKihm4hof9hgaMoxEA+/EPX7f0L/1rnPR39dkV1rbBojoV/XBd6w==}
engines: {node: '>=10'}
cpu: [x86, ia32]
os: [linux, freebsd]
'@supabase/supa-mdx-lint-linux-i686@0.3.1':
resolution: {integrity: sha512-09HNDDy11ox8IiEXe2SWecRtvdFOJu2lDvQo+vmEtVLhvO5eji65bG+vmESfdCcS79gaGxWoR+XWMreVhlVZ/Q==}
engines: {node: '>=10'}
cpu: [x86, ia32]
os: [linux, freebsd]
'@supabase/supa-mdx-lint-linux-i686@0.3.2':
resolution: {integrity: sha512-74J96VQzublrNAeNyVuymfBJM0teEWC4oCHVF6mdJ8sAJs4nGPv/QWG6aTFMzh2dvAlbS6jw4zlc0PoPluLCYg==}
engines: {node: '>=10'}
cpu: [x86, ia32]
os: [linux, freebsd]
'@supabase/supa-mdx-lint-linux-x64@0.2.6-alpha':
resolution: {integrity: sha512-nq0GB/WaqKyt4LWvx1+Z7XboSIlWtKmmqxyG1OtTQPcgKrImHvGrOJ3GuoUEcpJ9JyByCb2Tj3BJ6zIV8ngIJQ==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux, freebsd]
'@supabase/supa-mdx-lint-linux-x64@0.3.1':
resolution: {integrity: sha512-4ZioHRmm5Tt1/EF1K2FcmhrZVEYWcT+5z4smNvMqznutCXKowb3EYCtvDm1TOPXh8JjxzOnlch18+TN6MexsKA==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux, freebsd]
'@supabase/supa-mdx-lint-linux-x64@0.3.2':
resolution: {integrity: sha512-mort3Vc/LWNG9boV2QFnGHnPBWuKcNoOgkZXkjwqckAoMCpJ25dxVRmrGeQeP4MSiJSsw4+LTT0lfCegVgsr2w==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux, freebsd]
'@supabase/supa-mdx-lint-win32-i686@0.2.6-alpha':
resolution: {integrity: sha512-htjCjhElGSt9LTrtFHtN+iCsVHa4fZmVBBQPsO6Tqsubis00voFInKXkQGDsMkT9swOyEBCAaYe7XK3FEnYEXA==}
engines: {node: '>=10'}
cpu: [x86, ia32]
os: [win32]
'@supabase/supa-mdx-lint-win32-i686@0.3.1':
resolution: {integrity: sha512-u7H840/2fxjrLuNI2ohdslIyrZ8bJoBFhvTiC8J13cQBbpOP4FQOEzgeh1hqZGJNuWAUBgYJkwiZl/gc8Yv4Eg==}
engines: {node: '>=10'}
cpu: [x86, ia32]
os: [win32]
'@supabase/supa-mdx-lint-win32-i686@0.3.2':
resolution: {integrity: sha512-Fb2K/U2IpnoPQbXVSI51nG6Gd4C76SwXIs7RdAsXPgf1KTEh4R0YgzmBxqCVGL7flxPxmnMSM++QKDD9qqTslQ==}
engines: {node: '>=10'}
cpu: [x86, ia32]
os: [win32]
'@supabase/supa-mdx-lint-win32-x64@0.2.6-alpha':
resolution: {integrity: sha512-/hyZAA6SWMJsiPYeofN4NPkf6X/Fcywtls9I83PVFGYMaiK5jU2AvnjC22rMQSWgEFKKrF9K75yU7Qsd5teSpg==}
engines: {node: '>=10'}
cpu: [x64]
os: [win32]
'@supabase/supa-mdx-lint-win32-x64@0.3.1':
resolution: {integrity: sha512-AWAc7MwC0OU3NDuhZUVTVc1JYqXVY6UH6sL1lS/bM3j8eDAG1hTw2Bt4f85sAfYlt6BVDyEqLgNa3govsUQ5Jg==}
engines: {node: '>=10'}
cpu: [x64]
os: [win32]
'@supabase/supa-mdx-lint-win32-x64@0.3.2':
resolution: {integrity: sha512-3Bt4JVD1wwnDFrXoSZ1srV29w4RBWV5B5UITlG4EXBbpmOFDHbgH0nUbf65tSPzNEVIcwaW+5iFzwSi69gAbsA==}
engines: {node: '>=10'}
cpu: [x64]
os: [win32]
'@supabase/supa-mdx-lint@0.2.6-alpha':
resolution: {integrity: sha512-rfp+xsnTaQ/UB5LNNZEh6w00JxxkZMoZnjjIgb/TBvqr/E1DbWyLHSyWwMD8sBoC+LX8q20ym75GRAXhvxIONA==}
hasBin: true
'@supabase/supa-mdx-lint@0.3.1':
resolution: {integrity: sha512-TNbBLSofM6jQg3JwzO4lttd59dScTTzW4p504/OWcgRWghQLRNfxXRJJtdui83gBMLWpgeUZqvgtfYIwS1Flzw==}
hasBin: true
'@supabase/supa-mdx-lint@0.3.2':
resolution: {integrity: sha512-iqJHDk/ToyxFMa/um9A5gsp9jYN7iI0cIabNq9nyBpK/Yat/J9I2IIMueQwIMy3TsG6a2qdPyUkZkuPC37SdRg==}
hasBin: true
'@supabase/supabase-js@2.116.0':
resolution: {integrity: sha512-YyWmKXt2NspV9iO8FPnlswUFJIRnrLd3oTCb+3ZyYRuKZtBH0xCUDgnUqoyA0fGUxpM/UhfwDjYf/dht/9bp7g==}
engines: {node: '>=22.0.0'}
@@ -14933,9 +14789,6 @@ packages:
resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==}
engines: {node: ^18.17.0 || >=20.5.0}
nan@2.22.1:
resolution: {integrity: sha512-pfRR4ZcNTSm2ZFHaztuvbICf+hyiG6ecA06SfAxoPmuHjvMu0KUIae7Y8GyVkbBqeEIidsmXeYooWIX9+qjfRQ==}
nano-css@5.6.2:
resolution: {integrity: sha512-+6bHaC8dSDGALM1HJjOHVXpuastdu2xFoZlC77Jh4cg+33Zcgm+Gxd+1xsnpZK14eyHObSp82+ll5y3SX75liw==}
peerDependencies:
@@ -15140,9 +14993,6 @@ packages:
'@types/node':
optional: true
node-pty@1.0.0:
resolution: {integrity: sha512-wtBMWWS7dFZm/VgqElrTvtfMq4GzJ6+edFI0Y0zyzygUSZMgZdraDUMUhCIvkjhJjme15qWmbyJbtAx4ot4uZA==}
node-releases@2.0.53:
resolution: {integrity: sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==}
engines: {node: '>=18'}
@@ -25351,102 +25201,6 @@ snapshots:
iceberg-js: 0.8.1
tslib: 2.8.1
'@supabase/supa-mdx-lint-darwin@0.2.6-alpha':
optional: true
'@supabase/supa-mdx-lint-darwin@0.3.1':
optional: true
'@supabase/supa-mdx-lint-darwin@0.3.2':
optional: true
'@supabase/supa-mdx-lint-linux-arm64@0.2.6-alpha':
optional: true
'@supabase/supa-mdx-lint-linux-arm64@0.3.1':
optional: true
'@supabase/supa-mdx-lint-linux-arm64@0.3.2':
optional: true
'@supabase/supa-mdx-lint-linux-arm@0.2.6-alpha':
optional: true
'@supabase/supa-mdx-lint-linux-arm@0.3.1':
optional: true
'@supabase/supa-mdx-lint-linux-arm@0.3.2':
optional: true
'@supabase/supa-mdx-lint-linux-i686@0.2.6-alpha':
optional: true
'@supabase/supa-mdx-lint-linux-i686@0.3.1':
optional: true
'@supabase/supa-mdx-lint-linux-i686@0.3.2':
optional: true
'@supabase/supa-mdx-lint-linux-x64@0.2.6-alpha':
optional: true
'@supabase/supa-mdx-lint-linux-x64@0.3.1':
optional: true
'@supabase/supa-mdx-lint-linux-x64@0.3.2':
optional: true
'@supabase/supa-mdx-lint-win32-i686@0.2.6-alpha':
optional: true
'@supabase/supa-mdx-lint-win32-i686@0.3.1':
optional: true
'@supabase/supa-mdx-lint-win32-i686@0.3.2':
optional: true
'@supabase/supa-mdx-lint-win32-x64@0.2.6-alpha':
optional: true
'@supabase/supa-mdx-lint-win32-x64@0.3.1':
optional: true
'@supabase/supa-mdx-lint-win32-x64@0.3.2':
optional: true
'@supabase/supa-mdx-lint@0.2.6-alpha':
optionalDependencies:
'@supabase/supa-mdx-lint-darwin': 0.2.6-alpha
'@supabase/supa-mdx-lint-linux-arm': 0.2.6-alpha
'@supabase/supa-mdx-lint-linux-arm64': 0.2.6-alpha
'@supabase/supa-mdx-lint-linux-i686': 0.2.6-alpha
'@supabase/supa-mdx-lint-linux-x64': 0.2.6-alpha
'@supabase/supa-mdx-lint-win32-i686': 0.2.6-alpha
'@supabase/supa-mdx-lint-win32-x64': 0.2.6-alpha
node-pty: 1.0.0
'@supabase/supa-mdx-lint@0.3.1':
optionalDependencies:
'@supabase/supa-mdx-lint-darwin': 0.3.1
'@supabase/supa-mdx-lint-linux-arm': 0.3.1
'@supabase/supa-mdx-lint-linux-arm64': 0.3.1
'@supabase/supa-mdx-lint-linux-i686': 0.3.1
'@supabase/supa-mdx-lint-linux-x64': 0.3.1
'@supabase/supa-mdx-lint-win32-i686': 0.3.1
'@supabase/supa-mdx-lint-win32-x64': 0.3.1
node-pty: 1.0.0
'@supabase/supa-mdx-lint@0.3.2':
optionalDependencies:
'@supabase/supa-mdx-lint-darwin': 0.3.2
'@supabase/supa-mdx-lint-linux-arm': 0.3.2
'@supabase/supa-mdx-lint-linux-arm64': 0.3.2
'@supabase/supa-mdx-lint-linux-i686': 0.3.2
'@supabase/supa-mdx-lint-linux-x64': 0.3.2
'@supabase/supa-mdx-lint-win32-i686': 0.3.2
'@supabase/supa-mdx-lint-win32-x64': 0.3.2
node-pty: 1.0.0
'@supabase/supabase-js@2.116.0(@opentelemetry/api@1.9.1)':
dependencies:
'@supabase/auth-js': 2.116.0
@@ -33270,9 +33024,6 @@ snapshots:
mute-stream@2.0.0: {}
nan@2.22.1:
optional: true
nano-css@5.6.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6):
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
@@ -33603,11 +33354,6 @@ snapshots:
optionalDependencies:
'@types/node': 22.13.14
node-pty@1.0.0:
dependencies:
nan: 2.22.1
optional: true
node-releases@2.0.53: {}
non-error@0.1.0: {}
-32
View File
@@ -1,32 +0,0 @@
ignore_patterns = ["**/_*.mdx"]
# Heading should be sentence case
Rule001HeadingCase = "include('supa-mdx-lint/Rule001HeadingCase.toml')"
# Check spelling
# Error message: "Word not found in dictionary"
Rule003Spelling = "include('supa-mdx-lint/Rule003Spelling.toml')"
[Rule002AdmonitionTypes]
# Allowed admonition types are:
admonition_types = ["note", "caution", "deprecation", "danger"]
[Rule004ExcludeWords]
rules.filler = "include('supa-mdx-lint/Rule004ExcludeWords/filler.toml')"
rules.marketing = "include('supa-mdx-lint/Rule004ExcludeWords/marketing.toml')"
rules.vague_verbs = "include('supa-mdx-lint/Rule004ExcludeWords/vague_verbs.toml')"
rules.generic_phrases_apology = "include('supa-mdx-lint/Rule004ExcludeWords/generic_phrases_apology.toml')"
rules.first_person = "include('supa-mdx-lint/Rule004ExcludeWords/first_person.toml')"
rules.gender_neutral = "include('supa-mdx-lint/Rule004ExcludeWords/gender_neutral.toml')"
rules.inclusive_wording = "include('supa-mdx-lint/Rule004ExcludeWords/inclusive_wording.toml')"
rules.human_language = "include('supa-mdx-lint/Rule004ExcludeWords/human_language.toml')"
rules.latin_phrases = "include('supa-mdx-lint/Rule004ExcludeWords/latin_phrases.toml')"
rules.preferred_usage = "include('supa-mdx-lint/Rule004ExcludeWords/preferred_usage.toml')"
rules.formal_corporate = "include('supa-mdx-lint/Rule004ExcludeWords/formal_corporate.toml')"
rules.slang = "include('supa-mdx-lint/Rule004ExcludeWords/slang.toml')"
[Rule006NoAbsoluteUrls]
base_url = "https://supabase.com"
[Rule007NoHeadingsInAdmonitions]
level = "error"
-298
View File
@@ -1,298 +0,0 @@
# Heading should be sentence case
# Words that may be uppercased even if they are not the first word in the sentence.
# Can also specify a regex that is compatible with the [Rust regex crate](https://docs.rs/regex/latest/regex/).
may_uppercase = [
"[A-Z0-9]{2,5}s?",
"Option [A-Z]",
"Account component",
"Agent Skills",
"APIs",
"Add-ons?",
"Amazon RDS",
"Analytics",
"Android",
"Angular",
"Apache Spark",
"Apple",
"Assistant",
"Astro",
"Audit Log Drains?",
"Audit Logs?",
"Auth",
"Auth API Gateway",
"Auth0",
"Auth0 Actions?",
"AWS Marketplace",
"Azure",
"Azure Developers?",
"Azure MyApps",
"BigQuery",
"Bitbucket",
"Bitbucket Pipelines",
"Boolean",
"Branching",
"Broadcast",
"CAPTCHA",
"Catalog",
"Channel",
"ChatGPT",
"Chrome",
"Chrome Developer Tools",
"Clerk",
"Cloudflare",
"Cloudflare Workers?",
"Claude Code",
"Code Exchange",
"Colab",
"Compute",
"Compute Credits",
"Compute Hours",
"Content Delivery Network",
"Copilot",
"Cron",
"Cron Jobs?",
"Data API",
"Datadog",
"Dart",
"Dashboard",
"Database Functions?",
"Database Webhooks?",
"Deadpool",
"Dedicated Pooler",
"Deno",
"DigitalOcean",
"Discord",
"Discord Developers?",
"Disk",
"Django",
"Docker",
"Dockerfile",
"Drain",
"Drizzle",
"DuckDB",
"Edge Functions?",
"Editor",
"Egress",
"Embeddings API",
"Enterprise",
"Enterprise Plan",
"Events",
"Expo",
"Ethereum",
"Facebook",
"Facebook Developers?",
"Fair Use Policy",
"Fees",
"Figma",
"Figma Developers?",
"Firebase",
"Firebase Authentication",
"Firestore",
"Flask",
"Flutter",
"Functions?",
"Free Plan",
"Frequently Asked Questions",
"Git",
"GitHub",
"GitHub Actions",
"GitLab",
"GoTrue",
"Google",
"Google Workspace",
"Grafana",
"Grafana Cloud",
"GraphQL",
"Heroku",
"Homebrew",
"Hono",
"Hooks?",
"Hours",
"Hugging Face",
"I",
"IPv4",
"IPv6",
"IVFFlat",
"Iceberg",
"Identity Provider Initiated",
"IdP",
"Inbucket",
"Index Advisor",
"Integrations",
"IntelliJ",
"Ionic Angular",
"Ionic React",
"Ionic Vue",
"JavaScript",
"JSON Web Tokens?",
"JWTs",
"Kakao",
"Kakao Developers?",
"Kakao Login",
"Keycloak",
"Kotlin",
"Kotlin Multiplatform",
"Kysely",
"Laravel",
"Large Language Models?",
"LinkedIn",
"LinkedIn Developers?",
"Linux",
"LlamaIndex",
"Llamafile",
"Logs Explorer",
"Lovable",
"Lovable Cloud",
"Magic Link",
"Mailpit",
"Management API",
"Marketplace",
"Inspector",
"Metrics API",
"Mixpeek",
"Mixpeek Embed",
"Model Context Protocol",
"MySQL",
"Navigable Small World",
"Neon",
"Next.js",
"Nix",
"Node",
"Node.js",
"Notion",
"Nuxt",
"OAuth",
"Okta",
"Ollama",
"OpenAI",
"OpenID Connect",
"Open ID Connect",
"OpenMetrics",
"OpenTelemetry",
"OrbStack",
"OrioleDB",
"PGAudit",
"pgvector",
"Pandas",
"Partner Catalog",
"PgBouncer",
"Phoenix",
"Pro Plan",
"Podman",
"Poetry",
"Postgres",
"Postgres Changes",
"PostgreSQL",
"PostgREST",
"Presence",
"Prisma",
"PrivateLink",
"Prometheus",
"PyIceberg",
"Python",
"Qodo Gen",
"Queues?",
"Quotas",
"Query Performance",
"Rails",
"React",
"Reflex",
"Rollup",
"React Email",
"React Native",
"Read Replicas?",
"Realtime API Gateway",
"Realtime",
"Reciprocal Ranked Fusion",
"Redis",
"RedwoodJS",
"Refine",
"Remix",
"Render",
"Retrieval Plugin",
"Roboflow Inference",
"Row Level Security",
"Send Email Hook",
"SendGrid",
"Sentry",
"Server-Side Auth",
"Server-Side Rendering",
"Service Provider Initiated",
"Shared Pooler",
"Single Sign-On",
"Slack",
"Slack Developers?",
"Social Login",
"SolidJS",
"SolidStart",
"Spend Cap",
"Spotify",
"Spotify Developers?",
"Spring Boot",
"Spring Data JPA",
"Spring Initializr",
"Sqitch",
"Storage",
"Stripe Projects",
"Studio",
"Supabase",
"Supabase AI Assistant",
"Supabase Marketplace",
"Supavisor('s)?",
"Svelte",
"SvelteKit",
"Swift",
"SwiftUI",
"Solana",
"TanStack Start",
"Team Plan",
"Telegram",
"Third-Party Auth",
"TimescaleDB",
"TooManyChannels",
"Transformers.js",
"Twilio",
"Twitch",
"Twitch Developers?",
"Twitter",
"Twitter Developers?",
"TypeScript",
"Ubuntu",
"Uppy",
"Upstash",
"URIs",
"URLs",
"Unsplash",
"Usage",
"Xcode",
"Vault",
"VSCode",
"Vecs",
"Vector",
"Vercel",
"Vercel Fluid",
"Vercel Marketplace",
"Visual Studio Code",
"VM",
"Vite",
"Vue",
"Wasm",
"Web",
"WebAssembly",
"WebP",
"WebSockets?",
"WebStorm",
"Web3",
"Windows",
"WorkOS",
"Wrappers",
"Write-Ahead Log(s|ging)?",
"X",
"Zoom",
"Zoom Developers?",
]
# Words that may be lowercased even if they are the first word in the sentence.
# Can also specify a regex that is compatible with the [Rust regex crate](https://docs.rs/regex/latest/regex/).
may_lowercase = ["asyncpg", "iOS", "imgproxy"]
-553
View File
@@ -1,553 +0,0 @@
# Check spelling
# Error message: "Word not found in dictionary"
#
# Allow list: Spellings that are actually correct, though they aren't in the
# dictionary.
#
# Prefixes: Strings that are not standalone words, but that can be used in a
# prefix before a hyphen, such as "pre" or "bi".
#
# Before adding a new word to the allow list, double check that it is in fact
# the correct casing for the word! Especially for styling of company and product
# names, the "official" casing and spacing might not be what you think.
allow_list = [
"\\[#[A-Za-z0-9-]+\\]",
"\\$\\$.+?\\$\\$",
"\\s\\.[a-z]+",
"\\S+\\.js",
"\\S+\\.json",
"\\S+\\.toml",
"\\S+\\.yaml",
"[A-Z]{2,5}s?",
"[A-Za-z0-9_-]+(\\.[A-Z-a-z0-9_-]+)+(\\/[A-Za-z0-9_-]+)*",
"[Aa]dd-ons?",
"AAGUID",
"[Aa]fterward",
"[Aa]llowlists?",
"[Aa]uditability",
"[Aa]utomations?",
"[Aa]utovacuum(s|ing|ed)?",
"Azure MyApps",
"[Bb]ackends?",
"[Bb]ackoff",
"[Bb]lockchains?",
"BootEvent",
"BootFailure",
"[Bb]reakpoints?",
"[Bb]uilt-ins?",
"[Bb]undlers?",
"[Cc]anceled",
"[Cc]atalogs?",
"[Cc]hangelogs?",
"CircleCI",
"[Cc]odebases?",
"[Cc]odepaths?",
"[Cc]onfigs?",
"[Cc]onsecutiveness",
"[Cc]ooldowns?",
"[Cc]oroutines?",
"ComposeAuth",
"CPUTime",
"[Cc]ron",
"[Cc]rypto",
"[Cc]ryptography",
"[Cc]ryptosystem",
"[Cc]utover",
"[Dd]ata[Ff]rames?",
"dbpedia",
"[Dd]atasets?",
"[Dd]atasources?",
"[Dd]atetime",
"[Dd]e facto",
"[Dd]enylists?",
"[Dd]evs?",
"[Dd]iff(s|ing|ed)?",
"[Dd]ropdown",
"EarlyDrop",
"[Ee]m-dash",
"[Ee]m-dashes",
"[Ee]nqueues?",
"[Ee]ntrypoints?",
"[Ee]nums?",
"[Ee]nv",
"EventLoopCompleted",
"[Ee]x",
"[Ee]xecutables?",
"[Ee]xfiltrat(e|ed|es|ing)?",
"[Ff]astpath",
"[Ff]atals",
"[Ff]avors?",
"[Ff]ootguns?",
"[Ff]rontend",
"[Gg]apless",
"[Gg]eolocation",
"[Gg]lobs?",
"[Gg]lobstar",
"[Gg]rantor",
"[Gg]rayscale",
"[Gg]zip(s|ped|ping)?",
"[Hh]ealthcheck",
"[Hh]r",
"[Hh]ypertables?",
"[Ii]dempotency",
"[Ii]nstallable",
"[KMG]bps",
"[KMG]iB",
"[Kk]ubernetes",
"[Ll]iveness",
"[Ll]akehouses?",
"[Ll]odash",
"LogEvent",
"[Ll]oopback",
"[Ll]tree",
"[Mm]atryoshka",
"[Mm][Cc][Pp]",
"[Mm]essageBird",
"MetaMask",
"[Mm]icroservices?",
"microtasks",
"[Mm]iddlewares?",
"[Mm]iscapitalization",
"[Mm]isreport",
"[Mm]onorepos?",
"[Mm]ultibyte",
"[Mm]ultimodal",
"[Mm]ultipart",
"[Mm]ultithreading",
"[Nn]amespace(d|s)?",
"[Nn]o-ops?",
"[Nn]onces?",
"[Nn]ullable",
"[Oo]ffboarding",
"[Oo]h",
"[Oo]nboard(ing)?",
"[Oo]vercommit(s|ted|ting)?",
"[Pp]arallelization",
"[Pp]arams?",
"[Pp]asskeys?",
"[Pp]assthrough",
"[Pp]laintext",
"[Pp]olyfill(s|ed)?",
"[Pp]oolers?",
"[Pp]refetcher",
"[Pp]resign(ed|ing)?",
"[Pp]reload",
"[Pp]reloaded",
"[Pp]roxying",
"[Pp]sycopg",
"[Qq]uickstarts?",
"[Rr]ealtime",
"[Rr]eauthenticat(e|es|ed|ion)?",
"[Rr]ebas(e|ed|es|ing)",
"[Rr]emediat(e|ed|es|ing)",
"[Rr]eplayability",
"[Rr]epos?",
"[Rr]esultingly",
"[Rr]esyncs?",
"[Rr]untimes?",
"[Ss]anitization",
"[Ss]erverless",
"[Ss]erverside",
"[Ss]itekeys?",
"[Ss]tateful",
"[Ss]treamable",
"[Ss]tructs?",
"[Ss]ubcommands?",
"[Ss]ubdomains?",
"[Ss]ubfolders?",
"[Ss]ubmodules?",
"[Ss]ubpaths?",
"[Ss]wappiness",
"TerminationRequested",
"[Tt]imebox(ed)?",
"[Tt]odos?",
"[Tt]radeoffs?",
"[Tt]ransitives?",
"[Tt]unneled",
"UncaughtException",
"[Uu]ncomment(ing|ed)?",
"[Uu]nreferenced",
"[Uu]nlink(ing|s|ed)?",
"[Uu]ntracked",
"[Uu]pserts?",
"[Uu]ptime",
"[Vv]endored",
"[Ww]aitlists?",
"WallClockTime",
"[Ww]ebhooks?",
"WorkerMemoryUsed",
"Airbyte",
"Alertmanager",
"AWS Distro for OpenTelemetry",
"Adnan",
"AndroidX",
"AppleAuthentication",
"Artifactory",
"Astro",
"AsyncStorage",
"Authn",
"AuthRetryableFetchError",
"Authy",
"B-tree",
"Better Stack",
"Berri",
"Basejump",
"BigQuery",
"Bitbucket",
"Bitwarden",
"Bluesky",
"BotFather",
"Brevo",
"bytea",
"[Cc]addy",
"CAPTCHA",
"Cartes Bancaires",
"[Cc]ertbot",
"chatbot",
"ChatGPT",
"Citus",
"ClickHouse",
"Clippy",
"Cloudflare",
"CloudFront",
"CodeArtifact",
"codelab",
"Codium",
"Cognito",
"Colab",
"Corepack",
"Cyberduck",
"DBeaver",
"Database Functions?",
"Datadog",
"Deadpool",
"Dependabot",
"DepthFirst",
"DDoS",
"Deno",
"Dependabot",
"DevTools",
"DigitalOcean",
"DuckLake",
"Dinesh",
"Django",
"Docker",
"[Dd]ockerfile",
"[Dd]omainless",
"dotenvx",
"Drizzle",
"DuckDB",
"ElevenLabs",
"Elysia",
"[Ee]nablement",
"EnterpriseDB",
"Entra",
"[Ee]nvoy",
"[Ee]vals",
"ePHI",
"Erlang",
"ESZip",
"Ethereum",
"FastMCP",
"Fiberplane",
"Figma",
"Firecrawl",
"Firestore",
"Fivetran",
"Floyd-Warshall",
"GDScript",
"GSSAPI",
"Git",
"GitHub",
"GitLab",
"GoTrue",
"Golang",
"Grafana",
"Grafana OnCall",
"GraphQL",
"GraphiQL",
"Groonga",
"HackerOne",
"[Hh][Aa][Pp]roxy",
"HashiCorp",
"Heroku",
"hoc",
"Homebrew",
"Hono",
"Hyperdrive",
"HypoPG",
"IdP",
"ImageMagick",
"imgproxy",
"Inbucket",
"Inferencer",
"Infisical",
"Initializr",
"IntelliJ",
"IntelliSense",
"[Ii]nviter's",
"JFrog",
"IOWait",
"IVFFlat",
"JetBrains",
"JWTs",
"Jian",
"Jupyter",
"Kakao",
"Keycloak",
"Kotlin",
"Ktor",
"Kysely",
"LangChain",
"Laravel",
"[Ll]eaderboard",
"LineString",
"LinkedIn",
"LlamaIndex",
"Llamafile",
"lockfile",
"Logflare",
"[Ll]ookups?",
"Lovable",
"Lovable Cloud",
"Lua",
"Mailgun",
"Mailpit",
"Mailtrap",
"[Mm]akefile",
"Mansueli",
"Markprompt",
"Metabase",
"[Mm]in[Ii][Oo]",
"[Mm]itigations",
"Mixpeek",
"Multiplatform",
"MySQL",
"Nix",
"[Nn]amespaces?",
"[Nn]ano",
"NestJS",
"Netlify",
"Next.js",
"[Nn]ginx",
"NoSQL",
"Node.js",
"Nuxt",
"OAuth",
"Okta",
"Ollama",
"OneLogin",
"OpenAI",
"[Oo]pen[Aa][Pp][Ii]",
"OpenID",
"OpenMetrics",
"[Oo]pen[Ss][Ss][Ll]",
"Opsgenie",
"OrbStack",
"OrioleDB",
"OpenTelemetry",
"OTel",
"PaaS",
"PagerDuty",
"PGAudit",
"PGroonga",
"pg_basebackup",
"PgBouncer",
"pgcrypto",
"Pgcrypto",
"pgjwt",
"PHI",
"Pico",
"PingIdentity",
"Paulo",
# For historical purposes
"POSTGRES",
"PascalCase",
"Podman",
"PostGIS",
"PostQUEL",
"PostgREST",
"[Pp]ostgres",
"postgres-meta",
# We prefer Postgres, but check for vocabulary preference in a separate rule
"PostgreSQL",
"PowerBI",
"[Pp]refill",
"[Pp]roxied",
"ProGuard",
"PubSub",
"Prisma",
"PrivateLink",
"PyIceberg",
"Qodo",
"rclone",
"README",
"Redis",
"RedwoodJS",
"Refine",
"[Rr]etryable",
"Roboflow",
"[Rr]ollout",
"Rollup",
"[Rr]unbook",
"SaaS",
"[Ss]avepoint",
"SDKs",
"SQL",
"SQLSTATE",
"SQLAlchemy",
"SQLModel",
"SQLite",
"SecureStore",
"SendGrid",
"Session Timebox",
"sigstore",
"Snapchat",
"Snaplet",
"Snyk",
"Solana",
"Sonatype",
"SolidJS",
"SolidStart",
"Spotify",
"Sqitch",
"[Ss]ubfield(s)?",
"Supabase",
"[Ss]yslog(s)?",
"mTLS",
"Supavisor",
"SvelteKit",
"SwiftPM",
"SwiftUI",
"Reddit",
"Remapper",
"TablePlus",
"TextLocal",
"Thanos",
"TimescaleDB",
"tmux",
"TooManyChannels",
"[Tt]raefik",
"Transformers.js",
"tsquery",
"Twilio",
"UIKit",
"Undici",
"UnionPay",
"Unsplash",
"Uppy",
"Upstash",
"[Uu]pvote(s|d)?",
"userinfo",
"VSCode",
"Vecs",
"Verdaccio",
"Vercel",
"VictoriaMetrics",
"Vite",
"Vonage",
"Vue",
"Wasm",
"WebAuthn",
"WebAssembly",
"WebP",
"WebSockets?",
"WebStorm",
"WhatsApp",
"WorkOS",
"Xcode",
"Yang",
"Zapier",
"Zipkin",
"Zod",
"ZeptoMail",
"asyncpg",
"bcrypt",
"behaviors",
"[Bb]ackpressure",
"camelCase",
"dbdev",
"degit",
"deno-postgres",
"dotenv",
"e.g.",
"gte-small",
"halfvec",
"hCaptcha",
"Captcha",
"https?:\\/\\/\\S+",
"i.e.",
"imgproxy",
"undo-ing",
"sign ins",
"iOS",
"localStorage",
"localhost",
"macOS",
"magick-wasm",
"ms",
"ngrok",
"node-postgres",
"noop",
"npm",
"pnpm",
"npmrc",
"npx",
"ns",
"NVMe",
"pgAdmin",
"pgAudit",
"pgTAP",
"pgloader",
"pgmq",
"pgsodium",
"pgvector",
"plpgsql",
"postinstall",
"psql",
"safeupdate",
"scrypt",
"screencast",
"sessionStorage",
"signInWithIdToken",
"stdin",
"stdout",
"[Ss]ubnet(s)?",
"[Ss]ubpage",
"[Ss]ubstring",
"supabase-auth-ui",
"supabase-csharp",
"supabase-community",
"supabase-flutter",
"supabase-gdscript",
"supabase-grafana",
"supabase-go",
"supabase-js",
"supabase-kt",
"supabase-management-js",
"supabase-py",
"supabase-rb",
"supabase-swift",
"supautils",
"TanStack",
"tokio",
"tsvector",
"tvOS",
"visionOS",
"uBlock Origin",
"unbilled",
"unpublish",
"untrusted",
"UserInfo",
"vCPUs",
"vecs",
"vs",
"[Ww]alkthrough",
"watchOS",
"WebCrypto",
"[Xx]min",
"[Bb]ackfills?"
]
prefixes = ["bi", "over", "pre", "un"]
@@ -1,16 +0,0 @@
description = "Remove '%s' for a more concise, direct sentence."
level = "WARNING"
words = [
"actually",
"easily",
"easy",
"just",
"let's",
"obviously",
"of course",
"please",
"quickly",
"simple",
"simply",
"that's it",
]
@@ -1,3 +0,0 @@
description = "Don't use singular first person."
level = "ERROR"
words = ["I", "I'm", "me", "my", "mine"]
@@ -1,45 +0,0 @@
description = "Use a direct, simpler phrase instead of '%s'."
level = "WARNING"
words = [
[
"in order to",
"to",
],
[
"prior to",
"before",
],
[
"subsequent to",
"after",
],
[
"for the purpose of",
"to",
],
[
"leverage",
"use",
],
[
"whilst",
"while",
],
[
"amongst",
"among",
],
[
"facilitate",
"help",
],
[
"endeavor",
"try",
],
[
"endeavour",
"try",
],
"aforementioned",
]
@@ -1,20 +0,0 @@
description = "Don't use '%s' as a gender-neutral pronoun."
level = "ERROR"
words = [
[
"s/he",
"they",
],
[
"he/she",
"they",
],
[
"(s)he",
"they",
],
[
"him/her",
"them",
],
]
@@ -1,6 +0,0 @@
description = "Remove '%s' and state what happened directly. For example: 'Unable to connect to database' instead of 'Sorry, we couldn't connect'."
level = "WARNING"
words = [
"oops",
"sorry",
]
@@ -1,24 +0,0 @@
description = "Prefer '%r' to '%s'."
level = "WARNING"
words = [
[
"eg.",
"e.g.",
],
[
"eg",
"e.g.",
],
[
"i.e.",
"that is",
],
[
"ie.",
"that is",
],
[
"ie",
"that is",
],
]
@@ -1,24 +0,0 @@
description = "Replace '%s' with a more inclusive word."
level = "ERROR"
words = [
[
"mankind",
"humankind",
],
[
"manmade",
"manufactured",
],
[
"middleman",
"intermediary",
],
[
"blacklist",
"denylist",
],
[
"whitelist",
"allowlist",
],
]
@@ -1,5 +0,0 @@
description = "Prefer 'with', 'by', or 'through' instead of '%s', depending on context."
level = "WARNING"
words = [
"powered by"
]
@@ -1,15 +0,0 @@
description = "Remove '%s' to avoid marketing language and describe what the feature does specifically."
level = "WARNING"
words = [
"best in class",
"best-in-class",
"cutting edge",
"cutting-edge",
"effortlessly",
"game changer",
"game-changer",
"hassle free",
"hassle-free",
"powerful",
"seamlessly",
]
@@ -1,36 +0,0 @@
description = "Prefer '%r' to '%s'."
level = "WARNING"
words = [
[
"PostgreSQL",
"Postgres",
],
[
"concurrent clients",
"concurrent connections",
],
[
"utilize",
"use",
],
[
"utilise",
"use",
],
[
"utilizes",
"uses",
],
[
"utilises",
"uses",
],
[
"utilizing",
"using",
],
[
"utilising",
"using",
],
]
@@ -1,3 +0,0 @@
description = "Don't use Internet slang abbreviations"
level = "WARNING"
words = ["tl;dr", "ymmv", "rtfm", "imo", "fwiw"]
@@ -1,7 +0,0 @@
description = "Use '%r' instead of '%s'."
level = "WARNING"
words = [
["handle errors", "view and resolve errors"],
["manage tables", "create, edit, or delete tables"],
["work with data", "query and update data"],
]
-1
View File
@@ -2,7 +2,6 @@ rules:
dangerous-triggers:
ignore:
- "authorize-vercel-deploys.yml"
- "docs-lint-v2-comment.yml"
- "external-pr-comment.yml"
- "label_prs.yml"
- "studio-master-alert.yml"