Files
supabase/apps/docs/content/guides/local-development/seeding-your-database.mdx
T
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

208 lines
7.8 KiB
Plaintext

---
id: 'seeding-your-database'
title: 'Seeding your database'
description: 'Populate your database with initial data for reproducible environments across local and testing.'
subtitle: 'Populate your database with initial data for reproducible environments across local and testing.'
---
## What is seed data?
Seeding is the process of populating a database with initial data, typically used to provide sample or default records for testing and development purposes. You can use this to create "reproducible environments" for local development, staging, and production.
## Using seed files
Seed files are executed the first time you run `supabase start` and every time you run `supabase db reset`. Seeding occurs _after_ all database migrations have been completed. As a best practice, only include data insertions in your seed files, and avoid adding schema statements.
By default, if no specific configuration is provided, the system will look for a seed file matching the pattern `supabase/seed.sql`. This maintains backward compatibility with earlier versions, where the seed file was placed in the `supabase` folder.
You can add any SQL statements to this file. For example:
```sql
insert into countries
(name, code)
values
('United States', 'US'),
('Canada', 'CA'),
('Mexico', 'MX');
```
If you want to manage multiple seed files or organize them across different folders, you can configure additional paths or glob patterns in your `config.toml` (see the [next section](#splitting-up-your-seed-file) for details).
### Splitting up your seed file
For better modularity and maintainability, you can split your seed data into multiple files. For example, you can organize your seeds by table and include files such as `countries.sql` and `cities.sql`. Configure them in `config.toml` like so:
```toml supabase/config.toml
[db.seed]
enabled = true
sql_paths = ['./countries.sql', './cities.sql']
```
Or to include all `.sql` files under a specific folder you can do:
```toml supabase/config.toml
[db.seed]
enabled = true
sql_paths = ['./seeds/*.sql']
```
<Admonition type="note">
The CLI processes seed files in the order they are declared in the `sql_paths` array. If a glob pattern is used and matches multiple files, those files are sorted in lexicographic order to ensure consistent execution. Additionally:
- The base folder for the pattern matching is `supabase` so `./countries.sql` will search for `supabase/countries.sql`
- Files matched by multiple patterns will be deduplicated to prevent redundant seeding.
- If a pattern does not match any files, a warning will be logged to help you troubleshoot potential configuration issues.
</Admonition>
## Generating seed data
For most projects, a hand-written `supabase/seed.sql` (see [Using seed files](#using-seed-files) above) is the simplest and most reliable approach. If you need large volumes of realistic data, you can generate it with [Snaplet Seed](https://github.com/supabase-community/seed).
<Admonition type="note">
Snaplet wound down as a company in 2024 and open-sourced its tooling. `@snaplet/seed` is now community-maintained at [supabase-community/seed](https://github.com/supabase-community/seed) and receives only occasional fixes, so treat it as an optional convenience rather than a required part of the workflow.
</Admonition>
<Admonition type="note">
To use Snaplet, you need to have Node.js and npm installed. You can add Node.js to your project by running `npm init -y` in your project directory.
</Admonition>
If this is your first time using Snaplet to seed your project, you'll need to set up Snaplet with the following command:
```bash
npx @snaplet/seed init
```
This command will analyze your database and its structure, and then generate a JavaScript client which can be used to define exactly how your data should be generated using code. The `init` command generates a configuration file, `seed.config.ts` and an example script, `seed.ts`, as a starting point.
<Admonition type="note">
During `init` if you are not using an Object Relational Mapper (ORM) or your ORM is not in the supported list, choose `node-postgres`.
</Admonition>
In most cases you only want to generate data for specific schemas or tables. This is defined with `select`. Here is an example `seed.config.ts` configuration file:
```ts
export default defineConfig({
adapter: async () => {
const client = new Client({
connectionString: 'postgresql://postgres:postgres@localhost:54322/postgres',
})
await client.connect()
return new SeedPg(client)
},
// We only want to generate data for the public schema
select: ['!*', 'public.*'],
})
```
Suppose you have a database with the following schema:
```mermaid
erDiagram
User ||--o{ Post : createdBy
User ||--o{ Comment : userId
Post ||--o{ Comment : postId
User {
bigint id PK
text email
text name
}
Post {
bigint id PK
text title
text content
bigint createdBy FK
}
Comment {
bigint id PK
text text
bigint userId FK
bigint postId FK
}
```
This example schema has three tables. A `User` can author many `Post` rows (`Post.createdBy` references `User.id`) and many `Comment` rows (`Comment.userId` references `User.id`), and each `Post` can have many `Comment` rows (`Comment.postId` references `Post.id`). In other words, users create posts and comments, and every comment belongs to a post.
You can use the seed script example generated by Snaplet `seed.ts` to define the values you want to generate. For example:
- A `Post` with the title `"There is a lot of snow around here!"`
- The `Post.createdBy` user with an email address ending in `"@acme.org"`
- Three `Post.comments` from three different users.
```ts seed.ts
import { copycat } from '@snaplet/copycat'
import { createSeedClient } from '@snaplet/seed'
async function main() {
const seed = await createSeedClient({ dryRun: true })
await seed.Post([
{
title: 'There is a lot of snow around here!',
createdBy: {
email: (ctx) =>
copycat.email(ctx.seed, {
domain: 'acme.org',
}),
},
Comment: (x) => x(3),
},
])
process.exit()
}
main()
```
Running `npx tsx seed.ts > supabase/seed.sql` generates the relevant SQL statements inside your `supabase/seed.sql` file:
```sql
-- The `Post.createdBy` user with an email address ending in `"@acme.org"`
insert into "User" (name, email) values ('John Snow', 'snow@acme.org');
-- - A `Post` with the title `"There is a lot of snow around here!"`
insert into "Post" (title, content, createdBy)
values
('There is a lot of snow around here!', 'Lorem ipsum dolar', 1);
-- - Three `Post.Comment` from three different users.
insert into "User" (name, email) values ('Stephanie Shadow', 'shadow@domain.com');
insert into "Comment" (text, userId, postId) values ('I love cheese', 2, 1);
insert into "User" (name, email) values ('John Rambo', 'rambo@trymore.dev');
insert into "Comment" (text, userId, postId) values ('Lorem ipsum dolar sit', 3, 1);
insert into "User" (name, email) values ('Steven Plank', 's@plank.org');
insert into "Comment" (text, userId, postId) values ('Actually, that''s not correct...', 4, 1);
```
Whenever your database structure changes, you will need to regenerate `@snaplet/seed` to keep it in sync with the new structure. You can do this by running:
```bash
npx @snaplet/seed sync
```
You can further enhance your seed script by using Large Language Models to generate more realistic data. To enable this feature, set one of the following environment variables in your `.env` file:
```plaintext
OPENAI_API_KEY=<your_openai_api_key>
GROQ_API_KEY=<your_groq_api_key>
```
After setting the environment variables, run the following commands to sync and generate the seed data:
```bash
npx @snaplet/seed sync
npx tsx seed.ts > supabase/seed.sql
```
For more information, see the [Snaplet Seed repository](https://github.com/supabase-community/seed).