## Context
Shifts all remaining dashboard queries into pg-meta so that we
centralize all manually written queries in one place
Having them in packages/pg-meta also allows us to write tests for them
## To test
Just needs a smoke test on
- Role Impersonation
- Lints
- Data API
- Database
- Enumerated Types
- Integrations
- Foreign Data Wrappers
- Vault
## Context
Edge functions code editor which uses the FileExplorerAndEditor
component doesn't resize when the viewport shrinks
This PR fixes that + also refactors the FileExplorerAndEditor a bit to
resolve the lint issue with `nodeRenderer` by refactoring the prop into
a renderer that uses `useCallback`
## What kind of change does this PR introduce?
Chore that references DEPR-394.
## What is the current behavior?
Key/value editors for headers are implemented separately in multiple
places.
## What is the new behavior?
DEPR-394 is consolidating repeated RHF field-array UIs across Studio and
the design system.
- adds a shared `KeyValueFieldArray` component in `ui-patterns`
- adds a shared `httpHeaderAddActions` helper for preset header rows
- migrates the key/value header editors in:
- Platform Webhooks
- Cron Jobs HTTP headers
- Database Webhooks HTTP headers
- documents the key/value pattern in the design system with:
- a dedicated fragment page
- updated forms guidance
- updated form pattern demos
| Preview |
| --- |
| <img width="1102" height="420" alt="CleanShot 2026-03-23 at 12 22
18@2x"
src="https://github.com/user-attachments/assets/f8d23ff9-7063-462f-8074-b400561f77e9"
/> |
## Additional context
This is PR 1 of a 3-PR stack for DEPR-394.
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
This is a prototype for private apps UI. There are no endpoints at the
minute, just wanted to see what a potential flow could look like.
Adds `chatId` (the chat UUID) to the three assistant PostHog events so
we can count distinct chat sessions in PostHog. This naming is
consistent with how we name the field in Braintrust logs.
Also migrates from the deprecated `useSendEventMutation` hook to
`useTrack` — groups (project/org) are still sent automatically by
`useTrack`.
Closes AI-519
## Context
Shifting more dashboard queries into pg-meta so that we centralize all
manually written queries in one place
Having them in packages/pg-meta also allows us to write tests for them
## To test
Just needs a smoke test on
- Table Editor
- Fetching entities
- Viewing definition
- SQL Editor
- View ongoing queries
- Abort queries
- Integrations
- Queues
- Database
- Migrations
-Triggers (Updating)
Fixes#42089
Supersedes #43352 and
https://github.com/supabase/postgres-meta/pull/1049
## Problem
When creating a table in the Dashboard, if a column-specific error
occurs (e.g., invalid enum value or broken foreign key), the Dashboard
displays an error toast, but the side panel remains open. In the
background, the table is actually created (partially), leading to a
_42P07: relation already exists_ error if the user tries to click _Save_
again.
## Solution
We actually had nested transactions which is not supported by Postgres.
- [x] Allow generating SQL without transactions from `@supabase/pg-meta`
- [x] Fix the table creation
- [x] Fix some accessibility issues
- [x] Add tests
## How to test
1. Click _New table_ in the Table editor
2. Add a column with an _int8_ type and set its default value to
`bazinga`
3. Click _Save_
You should see an error.
4. Fix the default value by setting it to `10`
5. Click _Save_
Results:
- You should see a success message about the table creation
- The table should have the column with the correct default value
## Problem
PR #43704 added the `tableEditorApiAccessToggle` flag to revoke default
privileges on project creation, but there's no PostHog instrumentation
to measure the rollout or understand how users respond to the new
behavior.
## Changes
**1. Flag state on project creation**
(`project_creation_simple_version_submitted`)
Adds `tableEditorApiAccessToggleEnabled` property — reads the raw
PostHog flag via `usePHFlag` rather than going through
`useDataApiGrantTogglesEnabled`, which coerces `undefined` (flag still
loading) to `false` and would silently poison the data. When the flag
hasn't loaded, the property is omitted from the event entirely.
**2. Per-table toggle tracking** (`table_api_access_toggle_clicked`)
New event that fires when a user flips the Data API access switch in the
table editor side panel (new tables only — existing tables link out to
settings). Tracks `newState: 'enabled' | 'disabled'` and `schemaName` so
we can distinguish public-schema toggles from custom schemas.
Together these let us answer: what % of projects have the new defaults,
and how do those users respond (do they opt tables back in, and in which
schemas)?
Part of the Secure by Default initiative (#43704)
## Context
Similar to how we added a banner for the new table filter bar - mainly
to improve visibility for this feature preview as we'd like some
feedback from usage
<img width="313" height="314" alt="image"
src="https://github.com/user-attachments/assets/4cea6383-483a-42cf-b4a5-bb8c3918c00d"
/>
## Other changes
- Also adding some typing to the `addBanner` and `dismissBanner`
- Removed banner for table editor filter bar
When the `tableEditorApiAccessToggle` feature flag is enabled, project
creation now appends SQL to revoke default privileges for `anon`,
`authenticated`, and `service_role` on the `public` schema. This runs
after the base image init script's default grants. This is temporary
while we're still using a feature flag. Eventually it'll be moved into
the base image.
Applies to both the main project creation flow and the Vercel deploy
button flow.
Part of the "Secure by Default" initiative – new projects created under
this flag won't automatically expose tables/functions/sequences to the
Data API via default privileges. Users can still opt in at a table
level.
## Notes
Reusing the existing `useDataApiGrantTogglesEnabled()` flag here rather
than creating a new one – it's the same feature surface area and avoids
unnecessary flag proliferation.
## To test
1. **With flag enabled:**
- Enable the `tableEditorApiAccessToggle` flag in PostHog for your user
- Create a new project via the dashboard
- Create a new table
- Confirm in `/project/_/integrations/data_api/settings` that the new
table is not exposed by default
2. **With flag disabled:**
- Disable the flag (or use a different user without it)
- Create a new project
- Verify default privileges are intact and tables are accessible via the
Data API as usual
3. **With RLS event trigger enabled too:**
- Enable both the feature flag and the "enable RLS event trigger"
checkbox during project creation
- Verify both SQL statements run correctly on the new project
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
### FAQ (`type: 'faq'`)
Accordion-style FAQ with expand/collapse. Each item has a `question` and
`answer`. Click to toggle — only one open at a time.
<img width="1309" height="610" alt="Screenshot 2026-03-13 at 17 31 31"
src="https://github.com/user-attachments/assets/289c8a12-3835-4f64-bbe6-fb7095df4e7c"
/>
### Code Block (`type: 'code-block'`)
Syntax-highlighted code display using shiki with custom Supabase
dark/light themes. Supports:
- **Single file** — `code` + optional `filename` + `language`
- **Multi-file** — `files: [{ filename, code, language }]` with
clickable tabs
- Line numbers via CSS counters
- All highlighting runs at build time (server component), only tab
switching is client-side
<img width="1283" height="415" alt="Screenshot 2026-03-13 at 17 32 07"
src="https://github.com/user-attachments/assets/9cc9a215-d5c9-47c9-8e21-c1dd3beca4ba"
/>
### Steps (`type: 'steps'`)
Numbered step-by-step guide with a vertical timeline connector. Each
item has `title` and either a plain `description` string or a `content`
slot accepting any React node (e.g. images, code blocks).
<img width="1119" height="810" alt="Screenshot 2026-03-13 at 17 32 20"
src="https://github.com/user-attachments/assets/cb67aaab-9ed4-42e2-bf1c-8d836024e469"
/>
### Quote (`type: 'quote'`)
Centered testimonial block with `quote`, `author`, optional `role`, and
optional `avatar` image.
<img width="1095" height="238" alt="Screenshot 2026-03-13 at 17 32 37"
src="https://github.com/user-attachments/assets/356a39ca-9f65-4414-bf77-6060993594a4"
/>
This PR fixes some prettier issues:
- Bump and unify all prettier versions to 3.7.3 across teh whole repo
- Bump the SQL prettier plugin
- When running `test:prettier`, check `mdx` files also
- Run the new prettier format on all files
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
## What kind of change does this PR introduce?
UI touch-up
## What is the current behavior?
Explorer rows in file storage is a bit rough around the edges.
## What is the new behavior?
- Consistent loaders
- Consistent icons
Also includes:
- Fix to `stroke-width` on files-bucket.svg as documented in icons.mdx
| Before | After |
| --- | --- |
| <img width="1024" height="563" alt="Buckets Storage AWS Healthy
Toolshed Supabase"
src="https://github.com/user-attachments/assets/055518b2-6d93-4c9d-879b-6e7dd51e0620"
/> | <img width="1024" height="563" alt="Buckets Storage AWS Healthy
Toolshed Supabase"
src="https://github.com/user-attachments/assets/fae05446-95d9-4ca1-b441-7cd39d1c6036"
/> |
## What kind of change does this PR introduce?
Chore
## What is the current behavior?
- We use the MCP client connect dialog in two places: Studio and Docs
- We duplicate image assets for each client in each of those two places
## What is the new behavior?
- Centralised assets
- Consolidation and simplification as a result of it all being a single
source-of-truth now
## To test
- [ ] Everything works as it did before across both Studio and
[Docs](https://supabase.com/docs/guides/getting-started/mcp)
- [ ] All MCP client images load as expected
When the dashboard hits a DB connection timeout, users currently see a
raw error message with no
path forward. This PR adds an inline troubleshooting system that detects
known error types and
surfaces contextual next steps — restart the DB, read the docs, or debug
with AI.
## Changes
- New ErrorDisplay component (packages/ui-patterns) — styled error card
with a title, monospace error
block, optional troubleshooting slot, and a "Contact support" link that
always renders. Accepts
typed supportFormParams to pre-fill the support form.
- Error classification in handleError (data/fetchers.ts) — on every API
error, the message is tested
against ERROR_PATTERNS. If matched, handleError throws a typed subclass
(ConnectionTimeoutError
extends ResponseError) instead of a plain ResponseError. Stack traces
now show the exact error
class. All existing instanceof ResponseError checks continue to work.
- ErrorMatcher component — reads errorType from the thrown class
instance, does an O(1) lookup into
ERROR_MAPPINGS, and renders the matching troubleshooting accordion as
children of ErrorDisplay.
Falls back to plain ErrorDisplay for unclassified errors.
- Connection timeout mapping — first error type wired up, with three
troubleshooting steps: restart
the database, link to the docs, and "Debug with AI" (opens the AI
assistant sidebar with a
pre-filled prompt).
- Telemetry — three new typed events track when the troubleshooter is
shown, when accordion steps are
toggled, and which CTAs are clicked.
## Adding a new error type
1. Add a class to types/api-errors.ts
2. Add { pattern, ErrorClass } to data/error-patterns.ts
3. Create a troubleshooting component in errorMappings/
4. Add an entry to error-mappings.tsx
## Context
Related to FE-2557
Part of shifting manually written dashboard queries into
packages/pg-meta where
- pg-meta can be code owners of
- we can write tests for the queries
This PR just shifts all the `.sql.ts` files that we previously created
into packages/pg-meta
There's still other areas where we need to shift over as well which I'll
address in subsequent PRs
## Notable changes
- `getTableRowsCountSql` -> Opted to shift `formatFilterValue` logic out
before calling this method (ref `table-rows-count-query`)
- `getDeleteOldCronJobRunDetailsByCtidSql` -> Opted to shift
`validatePageNumber` logic out before calling this method (ref
`CronJobsTab.useCleanupActions`)
## Summary
Re-ports PR #43119 against the current `ProjectHome` codebase (the
original PR targeted `HomeNew/` which was removed during the `homeNew`
graduation in #43437). Also unifies the `connectSheet` and
`connectSection` feature flags into a single `connectSection` flag — the
`connectSheet` flag is removed entirely, so both the ConnectSheet
(header) and ConnectSection (homepage row) are controlled by one
experiment.
- Adds `connectSection` PostHog experiment flag that controls two
things:
1. Swaps the Getting Started section for a Connect section on the
project homepage for new projects (< 10 days old)
2. Swaps the legacy Connect dialog for the new ConnectSheet panel in the
header
- **Control** (`getting-started`): existing Getting Started section +
legacy Connect dialog in header
- **Treatment** (`connect`): new 4-tile Connect section + ConnectSheet
in header
- `undefined` (loading): neither section renders, avoiding flash
- Tiles filtered by the same `useIsFeatureEnabled` flags as ConnectSheet
(`show_app_frameworks`, `show_mobile_frameworks`, `show_orms`)
- Connect tile clicks tracked via `home_connect_action_clicked`; section
render tracked via `home_connect_section_exposed`; sheet opens tracked
via `connect_sheet_opened` with source attribution (`header_button` or
`connect_section`)
## Changes
- `packages/common/telemetry-constants.ts` — new
`home_connect_section_exposed`, `home_connect_action_clicked`, and
`connect_sheet_opened` event types
- `ConnectSheet/ConnectSheet.tsx` — read `connectTab` query param and
sync to active mode on open; `handleModeChange` keeps param in sync on
tab switch; fire `connect_sheet_opened` event with source attribution on
open
- `ConnectButton/ConnectButton.tsx` — set `connectSource=header_button`
query param on click
- `ProjectHome/ConnectSection.tsx` — new component (4-tile connect
card); set `connectSource=connect_section` on tile click
- `ProjectHome/Home.tsx` — experiment flag wiring
- `LayoutHeader/LayoutHeader.tsx` — read `connectSection` flag instead
of `connectSheet` to toggle ConnectSheet vs legacy Connect dialog
## Test plan
To test on the Vercel preview, set `connectSection=connect` to 100% in
PostHog (or override via cookie `ph_override_connectSection=connect`).
No separate `connectSheet` flag is needed — `connectSection` controls
both features.
- [x] Treatment (`connect` variant) — "Get connected" section renders on
new project, Getting Started hidden
- [x] Control (`getting-started`) — Getting Started renders, Connect
section hidden
- [x] Mature project (> 10 days) — neither section regardless of flag
- [x] Clicking each tile opens ConnectSheet on the correct tab
(Framework / Direct / ORM / MCP)
- [x] Switching tabs inside sheet updates `connectTab` URL param
- [x] Closing sheet clears `connectTab` param
- [x] Direct URL deep-link (`?showConnect=true&connectTab=orm`) opens
sheet on correct tab
- [x] Dark mode — background gradient renders correctly
- [x] Light mode — background switches to light gradient
- [x] Responsive layout — 4 cols (xl), 2×2 (md), stacked (mobile)
- [x] Telemetry — `home_connect_section_exposed` fires once on load;
`home_connect_action_clicked` fires with correct `mode`
- [x] Treatment — header Connect button opens ConnectSheet (not legacy
Connect dialog)
- [x] Control — header Connect button opens legacy Connect dialog (not
ConnectSheet)
- [x] Telemetry — clicking a ConnectSection tile fires
`connect_sheet_opened` with `source: 'connect_section'`
- [x] Telemetry — clicking header Connect button fires
`connect_sheet_opened` with `source: 'header_button'`
---------
Co-authored-by: Ali Waseem <waseema393@gmail.com>
## What kind of change does this PR introduce?
Feature
## What is the current behavior?
- Platform webhooks have a ‘tap target on tap target’ pattern with
`DropdownMenu` being on top of a clickable `TableRow`
- Misclicks are common (at least for me)
- @jordienr recently added the `hit-area` Tailwind plugin that helps
with misclicks
- https://github.com/supabase/supabase/pull/43636
## What is the new behavior?
- The aforementioned `DropdownMenu` in platform webhooks now uses
`hit-area` to avoid misclicks
- Design system documentation
- Extracted `hit-area` Tailwind plugin to shared packages so it can be
used in design-system as well as studio
## Preview
https://github.com/user-attachments/assets/89f9110a-6c99-4eed-a386-a6f646b1f4f6
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES/NO
## What kind of change does this PR introduce?
Bug fix, feature, docs update, ...
## What is the current behavior?
Please link any relevant issues here.
## What is the new behavior?
Feel free to include screenshots if it includes visual changes.
## Additional context
Add any other context or screenshots.
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Formalising our status code component that was introduced in the new
charts + update auth overview page.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a StatusCode UI component to display HTTP methods and status
codes with color-coded indicators.
* Added a demo showcasing multiple StatusCode examples and alignment
variants.
* **Documentation**
* Added a documentation fragment and sidebar entry for Status Codes with
a preview of the demo.
* **Refactor**
* Updated an Auth Overview view to use the new StatusCode component for
consistent status rendering.
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Context
Related to dashboard scalability
Previous PR: https://github.com/supabase/supabase/pull/42856
Note: Changes are all feature flagged still and I'm still not entirely
convinced with the current UX
Will iterate as as go along, and only make this publicly available when
we're satisfied with the behaviour
Adds a "Dashboard preference" section to the project settings
<img width="265" height="740" alt="image"
src="https://github.com/user-attachments/assets/6ce1aa19-26c2-47c6-a9c4-595137266631"
/>
In which users can then select which database they'd like to use for
read queries run from the dashboard
Note: Everything is local storage for now, but we'd need middleware
support if we want to make this setting persist for all users on the
project
<img width="791" height="434" alt="image"
src="https://github.com/user-attachments/assets/e651d6d9-fed4-4da4-b552-c9f93f8d46d3"
/>
Added a dialog as well to further explain what this implies
<img width="610" height="312" alt="image"
src="https://github.com/user-attachments/assets/0aa957af-cb51-476f-aa79-8948a7cbe5ae"
/>
## To test
- Choosing a replica in dashboard preferences will only affect the table
editor as thats the only place that's set up so far to use a replica for
read queries (I'll need to follow up for other parts of the dashboard in
subsequent PRs)
### Changes
- Adds a dismissible banner prompting paid org users to add a Tax ID to
their billing settings
- Only shown to users with billing read permissions on orgs with a paid
plan and no Tax ID set
- Dismissal is persisted per-org via localStorage; banner also
auto-hides when a Tax ID is added
### Testing
- Log in as a user with no billing permissions into a Free Plan Org with
no tax id: no banner is shown
- Log in as a user with billing permissions into a Free Plan Org with no
tax id: no banner is shown
- Log in as a user with billing permissions into a Paid Plan Org with no
tax id
- Assert banner appears at the top
- Head to `/org/_/billing` with a paid Org. Change your billing country
to a not support one (like Paraguay) and click save. Assert that the
banner disappears. Change it back to continue testing.
- Click dismiss: banner disappears and stays dismissed across
navigation/refresh
- Log in as a user with billing permissions into a different Paid Plan
Org with no tax id
- Add a Tax ID via billing settings, assert that the banner disappears
immediately
<img width="1911" height="50" alt="image"
src="https://github.com/user-attachments/assets/d6208d6d-0939-4ff6-9613-5c687e7c622e"
/>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
- Added tracker when the main ai button was pressed
- Added new event to track "Open in" third party apps
- Added 2 missing telemetry sources
## Problem
While working on the phased PostHog Attribution rollout (GROWTH-625 /
GROWTH-668) — specifically the initial referrer handoff across the app
boundary — we discovered that `parseFirstReferrerCookie` was returning
`null` even when the cookie was visibly present in the browser.
The root cause: `serializeFirstReferrerCookie` calls
`encodeURIComponent(JSON.stringify(data))`, but Next.js `cookies.set()`
encodes the value again, producing a double-encoded cookie. On the read
side, `parseFirstReferrerCookie` only decodes once, so `JSON.parse`
receives a still-encoded string and fails. The `try/catch` swallows the
error and returns `null`.
Confirmed in production: the raw cookie value starts with `%257B%2522`
(double-encoded `%` characters). A single `decodeURIComponent` produces
`%7B%22referrer%22...` — still URL-encoded, not valid JSON. This was
blocking the cross-app attribution handoff that GROWTH-625 depends on.
## Changes
- **Serializer**: Removed `encodeURIComponent` from
`serializeFirstReferrerCookie` — Next.js `cookies.set()` already handles
encoding
- **Parser**: Made `parseFirstReferrerCookie` resilient to both
encodings — tries single decode first, falls back to double decode for
existing cookies in the wild (365-day TTL means legacy cookies persist
up to a year)
- **Test**: Added unit test for the double-encoded legacy cookie format
## Testing
- 35/35 common unit tests pass, 12/12 www middleware tests pass
- Verified locally: Google → www (localhost:3000) → Studio
(localhost:8082). Console logs confirmed `parseFirstReferrerCookie`
returned the full data object instead of null
- Confirmed in production that existing cookies are double-encoded and
the fix correctly handles them
Ref: GROWTH-625 / GROWTH-668
Update reference rendering files to support additional values in tsdoc.
---------
Co-authored-by: Jonathan Summers-Muir <MildTomato@users.noreply.github.com>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Right now the new filter bar just does not work on mobile. It fully
collapses and does not appear correctly. This make it stack on smaller
screens and shows it to be visible. Works on smaller tabs
Note: there is a bit of awkwardness on certain screen sizes where its
one long row, will fix that later. This is better than nothing right now