Files
supabase/apps/docs/CONTRIBUTING.md
Miranda Limonczenko 0d465e7b5f chore(ui): Remove 'tip' from Admonition (#48419)
Closes FE-3966

## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## Problem

- The admonition uses both 'tip' and 'note', but the visual distinction
has long-ago collapsed.
- 'Note' is used far more frequently than 'tip'
- The two are very similar and it is confusing to know which one to use
when they are visually identical

## Solution

Collapse 'tip' and 'note' into one by removing all places where there is
'tip' and updating all references to 'tip' into 'note'.

**Note:** This PR also resolves new broken links flagged by the E2E docs
checker. It may move to another PR since E2Es keep erroring.

### Specific changes

See below for an AI-generated list of changes:

- **Type system** — removed `'tip'` from `AdmonitionType`, its
`TYPE_TO_VARIANT`/`TYPE_LABEL` entries, and the test case in
[`packages/ui-patterns/src/Admonition/](packages/ui-patterns/src/Admonition/)
- **Remark plugin** —
[remarkAdmonition.ts](apps/docs/lib/mdx/plugins/remarkAdmonition.ts) now
maps mkdocs `tip` → `note`
- **Lint allowlist** — `tip` dropped from `supa-mdx-lint.config.toml`
- **Content migration** — all 109 files with `type="tip"` (across
`apps/docs`, `apps/www`, `apps/studio`) converted to `type="note"`; zero
remaining hits confirmed by repo-wide grep
- **Style guide** — `CONTRIBUTING.md` and `contributing/content.mdx`
updated to describe 4 admonition types instead of 5

### Usage before implementation

See the usage table that points toward 'note' as being dominant across
all apps:

Here's the usage table:

| Location | `note` | `tip` |
|---|---|---|
| apps/docs | ~480 | ~143 |
| apps/studio | 34 | 6 |
| apps/www (blog) | 19 | 3 |
| packages/ui-patterns (tests) | 3 | 1 (parametrized) |
| design-system / ui-library / packages/ui / packages/common | 0–1 (test
fixture only) | 0 |

## Preview links


| App | Page | Search text (Ctrl+F) | Verify |
|---|---|---|---|
| docs |
[/docs/guides/ai-tools/byo-mcp](https://docs-git-admonition-collapse-note-tip-supabase.vercel.app/docs/guides/ai-tools/byo-mcp)
| official MCP TypeScript SDK | callout's aria-label="Note" |
| docs |
[/docs/guides/ai-tools/mcp](https://docs-git-admonition-collapse-note-tip-supabase.vercel.app/docs/guides/ai-tools/mcp)
| MCP server is available at | callout's aria-label="Note" |
| docs |
[/docs/guides/ai/python-clients](https://docs-git-admonition-collapse-note-tip-supabase.vercel.app/docs/guides/ai/python-clients)
| Click Connect at the top of any project page | callout's
aria-label="Note" |
| docs |
[/docs/guides/auth/audit-logs](https://docs-git-admonition-collapse-note-tip-supabase.vercel.app/docs/guides/auth/audit-logs)
| Disabling Postgres storage reduces your database storage costs |
callout's aria-label="Note" |
| docs |
[/docs/guides/database/tables](https://docs-git-admonition-collapse-note-tip-supabase.vercel.app/docs/guides/database/tables)
| access a custom schema through the Supabase Data API | callout's
aria-label="Note" |
| docs |
[/docs/guides/troubleshooting/edge-function-404-error-response](https://docs-git-admonition-collapse-note-tip-supabase.vercel.app/docs/guides/troubleshooting/edge-function-404-error-response)
| Always configure an appropriate time frame | callout's
aria-label="Note" (was single-quoted type='tip') |
| www | [blog:
cli-v2-config-as-code](https://zone-www-dot-com-git-admonition-collapse-note-tip-supabase.vercel.app/blog/cli-v2-config-as-code)
| Detecting config drift | callout's aria-label="Note" |
| www | [blog:
cli-v2-config-as-code](https://zone-www-dot-com-git-admonition-collapse-note-tip-supabase.vercel.app/blog/cli-v2-config-as-code)
| Setting Edge Function secrets | callout's aria-label="Note" |
| www | [blog:
nosql-mongodb-compatibility-with-ferretdb-and-flydotio](https://zone-www-dot-com-git-admonition-collapse-note-tip-supabase.vercel.app/blog/nosql-mongodb-compatibility-with-ferretdb-and-flydotio)
| If your network supports IPv6 connections | callout's
aria-label="Note" |

Note: the `www` rows use the `zone-www-dot-com` preview host, not the
`docs` one you gave — since blog pages are served from the www app, not
docs.


## Manual testing

1. Open preview links for affected pages.
2. Inspect. Open console.
3. Paste the following in and see there is no 'Tip' on the page:
```
document.querySelectorAll('[role="alert"]').forEach(el => console.log(el.getAttribute('aria-label'), el.textContent.slice(0,60)))
```



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

* **Documentation**
* Standardized informational callouts across docs and tutorials from
**“Tip”** to **“Note”**, updating multiple examples and guidance blocks.
* Updated a few related doc references/links and conditional “Next
steps” content.
* **UI Updates**
* Switched various in-app banners and notices to the **“Note”** style
variant.
* **Bug Fixes / Improvements**
* Removed support for the retired **“Tip”** callout type and aligned
docs linting, component behavior, and aria labeling to the remaining
admonition types.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-29 09:26:50 -07:00

23 KiB

Contributing to Supabase docs

Our docs help developers to get started and keep succeeding with Supabase. We welcome contributions from everyone.

If you'd like to contribute, see our list of recommended issues. We also welcome you to open a PR or a new issue with your question.

Here are some general guidelines on writing docs for Supabase.

General principles

Write helpful, concise, and understandable documentation. We have a global audience whose members speak different native languages.

To make docs as clear as possible:

  • Write for the user. Think about what task they want to complete by reading your doc. Tell them what, and only what, they need to know.
  • Write like you talk. Conversational English is easier for a global audience to understand and localize. Many readers who use English as an additional language learn conversational rather than academic English. Use words and sentences that sound natural when speaking. Cut unnecessary words. Read your writing out loud to help you choose the clearest and simplest phrases.
  • Prefer short, direct sentences. Express one relationship at a time, and avoid unnecessary compound structures. This makes each sentence easier to understand, localize, and interpret consistently.
  • Cover one topic in each paragraph. Start a new paragraph whenever you change the topic. Don't worry about paragraphs being too short.
  • Avoid using idioms and colloquialisms, such as piece of cake. These phrases are often specific to a region or culture.
  • Refer to the reader as you. Don't use we to refer to the reader. Use we only to refer to the Supabase team.

Document types

Supabase docs contain 4 types of documents. Before you start writing, think about what type of doc you need.

Explainers

Explainers help the reader to learn a topic. They are conceptual and mostly prose-based. They can include:

  • A description of what a feature is
  • Some reasons why it is useful
  • Some examples of when to use it
  • A high-level explanation of how it works

Explainers don't include:

  • Instructions on how to use it

Tutorials

Tutorials are goal-oriented. They help a reader to finish a large, complex goal, such as setting up a web app that uses multiple Supabase features.

Tutorials mix prose explanations with procedures. Procedures are lists of steps for the reader to follow. Tutorials provide context for why certain instructions are given.

For inspiration, see an example of a tutorial.

Guides

Guides are also goal-oriented, but they focus on shorter, more targeted tasks. For example, a guide might explain how to set up user login for an app.

Guides contain mostly procedures: concise steps that readers can follow in sequence.

Begin each guide with a sentence that declares its intent, such as This guide explains how to set up email login. This helps readers and agents confirm that the guide matches their goal and expected outcome.

Keep procedures focused on what the reader must do. Move substantial background or conceptual explanations into a separate section or an explainer. Cross-reference the authoritative explanation instead of repeating it in the procedure. This keeps the action path scannable, gives readers optional depth, and maintains one source of truth.

  • Recommended: This guide explains how to enable Row Level Security. To learn how Row Level Security controls access, see [Row Level Security](...).
  • Not recommended: Begin with several paragraphs about how Row Level Security works before stating what the guide helps the reader do.

Mixed information types: When a guide contains substantial context or reference material, group sections by information type. Keep contextual and reference sections separate from the procedure group so that background information doesn't interrupt the action path.

Navigation: Begin a long guide with a short outline of its major section groups. Link to each group and state when a reader should use it. Don't add section navigation to a short guide when the headings are already easy to scan.

Cross-references and glue: Connect contextual sections to their corresponding procedures when the relationship helps readers navigate. Add a brief introduction to each section group, a transition when the information type changes, and an outcome after a procedure. Add links selectively rather than linking every adjacent section.

For inspiration, see an example of a guide.

Reference

References are factual and to the point. Think of dictionary entries.

References include:

  • Function parameters
  • Return types
  • Code samples
  • Warnings about critical errors, such as missteps that can cause data loss

References don't include:

  • Explanations of the context for a feature
  • Examples of use cases
  • Multi-step instructions

Repo organization

Most docs pages are contained in the apps/docs/content directory. Some docs sections are federated from other repositories, for example pg_graphql. Reference docs are generated from spec files in the spec directory.

You can usually identify a federated or reference doc because it uses a Next.js dynamic route. For example, it might use [[...slug]].tsx. Look for the spec file import or the repo definition to find the content location.

Example spec file import:

import specFile from '~/spec/transforms/analytics_v0_openapi_deparsed.json' with { type: 'json' }

Example repo definition:

const org = 'supabase'
const repo = 'pg_graphql'
const branch = 'master'
const docsDir = 'docs'
const externalSite = 'https://supabase.github.io/pg_graphql'

Check the sections for guide structure and reference structure to learn more about the file structures.

Guide structure

The Supabase docs use MDX. Guides are MDX documents that combine concise prose with structured procedures.

Adding a new guide requires:

  • YAML frontmatter
  • A navigation entry in a separate file

Frontmatter looks like this. title is mandatory. There are also optional properties that you can use to control the page display, including subtitle, tocVideo, and hideToc.

---
title: How to connect to Supabase
hideToc: true
---

The navigation is defined in NavigationMenu.constants.ts.

Add an entry with the name, url, and optional icon for your page.

Reference structure

Reference docs are produced from the reference specs and library source code. A common spec file contains shared function and endpoint definitions, and library-specific spec files contain further details.

Common spec file

Each type of library, such as a language SDK or CLI, has a common spec file. For example, see the spec file for the language SDKs. This file contains definitions for the common SDK functions:

  • id: Identifies the function
  • title: Provides the human-readable title
  • slug: Provides the URL slug
  • product: Identifies the Supabase product that owns the function. For example, database operations are owned by database, and Auth operations are owned by auth.
  • type: Uses function for a structured function definition or markdown for a prose explainer section

To add a new function, manually add an entry to this common file.

Specific spec file

Each library also has its own spec file containing library-specific details. For example, see the JavaScript SDK spec file.

The functions listed in this file match the ones defined in the common spec file.

Each function contains a description, code examples, and optional notes. The parameters are pulled from the source code via the $ref property, which references a function definition in the source code repo. These references are pulled down and transformed using commands in the spec Makefile. Unless you're a library maintainer, you don't need to worry about this.

If you're a library maintainer, follow these steps when updating function parameters or return values:

  1. Merge your changes into the library's master branch.
  2. Wait for the action to update the specification in the gh-pages branch.
  3. Run make from apps/docs/spec in the supabase/supabase repository.
  4. Verify the changes on your local documentation site.

Content reuse

If you copy the same content multiple times across different files, create a partial for content reuse instead. Partials are MDX files contained in apps/docs/content/_partials. They contain reusable snippets that can be inserted in multiple pages. For example, you can create a partial to define a common setup step for a group of tutorials.

To use a partial, import it into your MDX file. You can also set up a partial to automatically import by including it in the components within apps/docs/features/docs/MdxBase.shared.tsx.

Components and elements

Docs include normal Markdown elements such as lists and custom components such as admonitions, also known as callouts.

Here are some guidelines for using elements:

Admonitions

Admonitions draw reader attention to an important point or an aside. They highlight important information, but get less effective if they're overused.

Use an admonition when a reader might otherwise miss information that affects the outcome of their task, or when you want to separate helpful but optional guidance from the main flow. Don't use an admonition for information that belongs in the main explanation or procedure.

Use admonitions sparingly. Don't stack them on top of each other or use them as decoration.

Begin every admonition with its impact and purpose: the "so what." Use the first sentence to tell the reader why the information matters, such as what could happen, what changes, or what benefit they gain. Add background or instructions after the impact is clear.

For example:

  • Recommended: Deleting this project permanently removes its database and backups. Export any data that you want to keep before you continue.
  • Not recommended: Before you continue, there are a few things that you should know about project deletion.

Choose the appropriate type for your admonition:

  • danger: Warn about actions or conditions that could cause data loss, expose sensitive data, or create another severe and difficult-to-reverse outcome. State the consequence first, and then explain how to avoid it.
  • deprecation: Identify a deprecated feature or behavior. State how the change affects the reader, and then provide the supported alternative or migration path.
  • caution: Warn about behavior that could cause bugs, failed operations, unexpected results, or serious inconvenience but doesn't rise to the severity of danger.
  • note: Highlight an important prerequisite, constraint, clarification, or optional shortcut that doesn't represent a risk. If the information is essential to completing a step, include it in the procedure instead.
<Admonition type="note" title="Optional title">

Your content here

</Admonition>

Blockquotes

Don't use blockquotes.

Code blocks

Keep code lines short to avoid scrolling. For example, you can split long shell commands with \.

  • JavaScript/TypeScript

    The supabase repository uses Prettier, which also formats JS/TS in code blocks. Your PR is blocked from merging if the Prettier check fails. From the repository root, run pnpm format, or set up automatic formatting in your IDE.

  • SQL

    Prefer lowercase for SQL. For example, select * from table rather than SELECT * FROM table.

Optionally specify a filename for the code block by including it after the opening backticks and language specifier:

```ts environment.ts

```

Optionally highlight lines by using mark=${lineNumber}.

```js mark=12:13

```

Emphasis

Use bold, italics, and code formatting for distinct purposes. Don't use them interchangeably or to add visual emphasis alone.

  • Bold: Mark UI labels the reader interacts with, such as buttons, menu items, and field names. For example, Click **Save**. Also use bold for a term the reader must not miss, such as **Never** commit your service role key.
  • Italics: Introduce a new term the first time you define it, or reference a title, such as a book or a third-party product name written in italics by convention. Use italics sparingly. Don't use italics for UI labels or for general emphasis.
  • Code: Mark anything the reader types or copies verbatim, or anything the system reads literally. This includes filenames, paths, commands, flags, environment variables, function and parameter names, configuration keys, and literal values. For example, Set `SUPABASE_URL` in your `.env` file.

If a phrase fits more than one category, pick the most specific one. A command name is code, not bold, even though the reader also interacts with it.

Content listings

Overview and index pages use a single <ContentListings id="..." /> component for curated link sections such as "Get started", "Next steps", "Examples", or "Resources". Refer to storage.data.ts and storage.mdx for a full example.

Prompt to add content listings:

Add a content listing block for [TOPIC] / [SECTION]. For example, use Storage / Examples.
Follow CONTRIBUTING § Content listings in apps/docs.
Copy structure from `storageGetStarted` in apps/docs/data/content-listings/storage.data.ts.
Pick a globally-unique kebab-case id like `[topic]-[section]`.
Run `pnpm test:local lib/content-listings.test.ts` from apps/docs.

Manually add content listings:

  1. Add or update a ContentListingGroup export in data/content-listings/[topic].data.ts. The id field must be globally unique across all listing groups. For example, use storage-get-started rather than get-started. The ID is both the lookup key and the telemetry listingId.
  2. Place the component inline in guide MDX, for example <ContentListings id="storage-get-started" />. Use a partial only when the block is reused or gated with $Show at the partial level.
  3. Run pnpm test:local lib/content-listings.test.ts from apps/docs.

Code snippets for manually adding content listings are available in .vscode/content-listing.code-snippets. Use cl-data for a data export with a namespaced ID. Use cl-inline for an MDX component.

Footnotes

Don't use footnotes.

Graphs

Render diagrams, including flowcharts, sequence diagrams, and entity-relationship diagrams, by writing a fenced code block with mermaid as the language. The MDX renderer routes these blocks through the shared Mermaid component, so theming follows light and dark mode automatically.

For the full list of supported diagram types and their syntax, see the official Mermaid diagram reference.

Sequence diagram:

```mermaid
sequenceDiagram
  participant User
  participant Browser
  participant Supabase

  User->>Browser: Clicks "Sign in"
  Browser->>Supabase: Request authorization
  Supabase->>Browser: Return token
```

The flowchart keyword accepts a direction such as LR or TD:

```mermaid
flowchart LR
  A["content/**/*.md"] -->|Contentlayer| B[MDX]
  B --> C[Rehype]
  C -->|Our Plugin| D[SVG]
  D -->|Base64| E[Embedded Images]
```

A few tips:

  • Use a standard Mermaid diagram keyword, such as sequenceDiagram, flowchart, or erDiagram, on the first line of the block.
  • Keep diagrams focused on a single flow or concept. If a diagram gets too dense, split it into multiple smaller diagrams.
  • Wrap node labels that contain special characters in double quotes. Special characters include *, /, spaces, and punctuation. For example, use A["content/**/*.md"].
  • Don't hardcode colors. The component themes the diagram automatically so it matches both light and dark mode.
  • Use diagrams to support the prose, not replace it. Explain the key takeaway in text near the diagram.

Images

Images are uploaded in the apps/docs/public/img folder.

For vector illustrations, use .svg files. For screenshots and non-vector graphics, use .png files. Supported browsers receive .webp versions automatically.

Redact any sensitive information, such as API keys.

Use descriptive link text that tells the reader where the link goes. This is important for accessibility. For example, don't use here as link text.

Keep link text concise. Use the shortest part of the link that is descriptive enough. For example, see the [reference section](/link) rather than [see the reference section](/link).

Don't include the https://supabase.com origin when linking to pages on supabase.com. Use a /docs/... path for a page in Supabase docs, such as [getting started](/docs/guides/getting-started). Use a site-root path for a page outside docs, such as [open the Supabase Dashboard](/dashboard).

Procedures

Use a procedure when a human or agent must perform actions to reach an outcome. The procedural format makes that expectation explicit.

Write sequential actions as an ordered list. Begin each step with an imperative verb, and include one action or a closely related set of actions per step. Give the reader enough context to know where to act.

Apply the Information Mapping chunking principle to procedures. Present 7 ± 2 related steps at a time. This gives readers a manageable chunk of five to nine actions. Aim for the lower end of the range when the task is complex or unfamiliar.

If a procedure has more than nine steps, group related steps into named phases or smaller procedures. If one step contains multiple distinct actions, split it into separate steps. Don't add steps to reach a minimum. The range is a guideline for organizing information, not a required procedure length.

An apparent one-step procedure can become two steps when there is a real orientation action. For example:

  1. Open a terminal in your project directory.
  2. Run supabase start.

The first step establishes the operating context for both readers and agents. Don't add a redundant orientation step to a genuinely atomic instruction. For example, write Click **Save**. instead of adding Locate the **Save** button as a separate step.

Lists

Use ordered lists for steps that must be taken one after the other. Use unordered lists when order doesn't matter.

Use Arabic numerals (1, 2, 3) for ordered lists and dashes (-) for unordered lists.

Don't nest lists more than two deep.

1. List item
2. List item
   1. List item
   2. List item
3. List item
   - List item
   - List item
     <!-- DON'T ADD ANOTHER LEVEL OF NESTING -->
     - Overly nested list item

Tabs

Use tabs to provide alternative instructions for different platforms or languages.

The optional queryGroup prop lets you link directly to a tab. For this example, use /docs/my-page?packagemanager=npm.

<Tabs
  scrollable
  size="small"
  type="underlined"
  defaultActiveId="npm"
  queryGroup="packagemanager"
>
<TabPanel id="npm" label="npm">

// ...

</TabPanel>
<TabPanel id="yarn" label="Yarn">

// ...

</TabPanel>
</Tabs>

Videos

Include videos as table of contents (TOC) videos instead of placing them in the main text.

You can define a TOC video in the page frontmatter:

---
tocVideo: 'rzglqRdZUQE'
---

Styling, formatting, and grammar

Grammar is useful when it makes your writing clearer. Use complete sentences by default because they identify the actor and action. This reduces ambiguity for readers, translators, and agents. Use sentence fragments only where they improve scanning, such as headings, labels, or short list items.

Headings guide the reader's eye and organize the page, but they don't carry information by themselves. Make the content beneath a heading understandable without relying on the heading. The first sentence can restate the heading, even if it sounds redundant. Readers often skim headings and then return to the section that interests them, so use the opening sentence to confirm the context.

Don't use parentheses for asides or supplementary information. Rewrite that information as part of the sentence or as a separate sentence. Use parentheses to introduce an acronym after spelling out its meaning, such as full-text search (FTS), or to mark an item as (Optional). Parentheses that are required by Markdown links or code syntax aren't prose parentheticals.

That said, a few rules help keep the docs concise, consistent, and clear:

  • Format headings in sentence case. Capitalize the first word and any proper nouns. All other words are lowercase. For example, Set up authentication rather than Set Up Authentication.
  • Use the Oxford comma. Place a comma before the and that marks the last item in a list. For example, use functions, tables, and indexes rather than functions, tables and indexes.
  • Use the present tense as much as possible. For example, the AI assistant answers your question rather than the AI assistant will answer your question.

Word usage and spelling

Use American English. If in doubt, consult the Merriam-Webster dictionary.

Follow the Supabase documentation word list 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.

Search uses a Supabase instance. During CI, a script collects guides, reference documentation, and other content. The script creates OpenAI embeddings and stores the search index in a Supabase database.

Search combines native Postgres full-text search (FTS) with embedding similarity search based on pgvector. At runtime, a PostgREST call invokes the weighted FTS RPC. An Edge Function runs the embedding search.