## Context
Table Editor - hide "Is unique" configuration for a column that's a
primary key - unnecessary to configure a column as unique if it's
already a primary key (redundant index is created)
## Changes involved
- TableEditor side panel: No longer shows is unique option under
configuration popover if column is a PK
- ColumnEditor side panel: Disable is unique + is nullable option if
column is a PK (Added tooltip)
<img width="810" height="151" alt="image"
src="https://github.com/user-attachments/assets/0f877706-1a56-44b7-864e-ba30efbb67f7"
/>
Also chucked in some minor refactors:
- Refactored some `any` types
- Refactored Column to use the latest Checkbox component
## Problem
The edge function logs table at
`/observability/logs/edge-functions-logs` did not show which edge
function was called. Users had to open individual log entries to find
the function name, even though the information is available in the log
data.
## Fix
- Added `request.pathname` to the SQL SELECT query for
`function_edge_logs` so the pathname is returned with each row.
- Added `extractEdgeFunctionName` utility that parses the last path
segment from the pathname (e.g. `/functions/v1/hello-world-1` becomes
`hello-world-1`).
- Updated `FunctionsEdgeColumnRender` to display the function name
between the HTTP method and the log ID columns.
- Added unit tests for `extractEdgeFunctionName` covering normal paths,
null/undefined, non-string values, and pathnames without slashes.
<img width="1472" height="776" alt="CleanShot 2026-03-19 at 13 18 47@2x"
src="https://github.com/user-attachments/assets/e437f7df-7aab-4ea5-b421-95bab3923605"
/>
## How to test
- Navigate to Logs and Analytics, then Edge Functions logs.
- Confirm each row now shows the function name (e.g. `hello-world-1`)
between the HTTP method and the log ID.
- Confirm rows without a pathname (e.g. non-platform or self-hosted)
still render without errors.
- Confirm clicking a row still opens the log detail panel correctly.
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
## Context
If you've got a queued operation on a table, then switch tables, the
dashboard stalls for a few seconds before finally rendering the selected
table.
This was caused by an infinite loop in a useEffect calling
`reapplyOptimisticUpdates` due to `dataUpdatedAt` being in the
dependency array (which comes from react query)
Removing `dataUpdatedAt` would resolve the issue, but then it won't
solve the following comment in the code:
`// This ensures pending changes remain visible when switching tabs or
after data refresh`
## Changes involved
Opting to refactor the logic for rendering data in the Grid instead
- Avoid manipulating the data directly from the query client
- Manual changes to the query client are hard to track when debugging
- Ideally the data in the query client are exactly what is coming from
the API
- Instead just compute the row data if there's operations applied, and
render that in the grid
```
const baseRows = data?.rows ?? EMPTY_ARR
const rows = formatGridDataWithOperationValues({ operations, rows:
baseRows })
```
- Simplifies operations logic + data in react query remains as the
source of truth
- This also improves perceived performance, as previously we'd need to
invalidate the query client if we're removing any operation.
- A lot more apparent with the undo operation introduced
[here](https://github.com/supabase/supabase/pull/43957)
- Whereas now, we'll just revert back to whatever's in the query client
(and still do the invalidation behind the scenes) so things feel faster
## 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
<img width="1543" height="981" alt="image"
src="https://github.com/user-attachments/assets/8e6c37c5-15c7-4bc4-be87-477e36a62a65"
/>
Switches from two to one column layout for details page and removes an
inconsistent background colour in header. Moves critical detail
information from page into header (url and deploy dates/counts)
## What kind of change does this PR introduce?
Bug fix. Resolves FE-2802. Fixes#43882.
## What is the current behavior?
Second-level foreign key side panels in Table Editor can be dismissed
while dirty without a discard confirmation. That makes accidental
dismissal easy and is inconsistent with the shared dirty-form dismissal
pattern from FE-2802.
## What is the new behavior?
- Adds `DiscardChangesConfirmationDialog` handling to
`ForeignKeySelector`
- Guards all selector close paths behind a local dirty-state check
- Normalizes foreign key state so derived type metadata does not create
false dirty prompts
- Clarifies in `modality.mdx` that route-driven/page-unload flows should
use a navigation guard rather than the dialog/sheet close guard
| Dirty State | Dialog |
| --- | --- |
| <img width="1502" height="899" alt="test Table Editor AWS Healthy
Toolshed Supabase-D1EA9D5F-46EB-4DB5-830D-7CEF36A55B7E"
src="https://github.com/user-attachments/assets/3d866850-d062-4fb7-9949-2fd713e6088f"
/> | <img width="1502" height="899" alt="test Table Editor AWS Healthy
Toolshed Supabase"
src="https://github.com/user-attachments/assets/1396361d-1d44-4206-862f-3379ea22be30"
/> |
## Additional context
Includes a focused unit test for foreign key dirty-state normalization.
## What kind of change does this PR introduce?
Bug fix.
## What is the current behavior?
Webhook endpoint validation is inconsistent across Studio forms. The
webhook sheet accepts incomplete hostnames like `https://webhook`, event
type validation is not surfaced clearly, and HTTP endpoint validation
differs between webhooks, log drains, cron jobs, and database hooks.
## What is the new behavior?
- Tightens webhook endpoint URL validation and rejects incomplete
hostnames while still allowing localhost and IP-based endpoints.
- Surfaces the Event types validation through the standard form error
styling and highlights the existing accordion item border when invalid.
- **Extracts a shared HTTP endpoint URL validator and reuses it in
webhooks, log drains, cron jobs, and database hooks.**
- Adds focused regression tests for the webhook sheet and the
shared/consumer validation paths.
| After |
| --- |
| <img width="1728" height="997" alt="Webhooks Settings AWS Healthy
Toolshed Supabase-CB0D999C-D0BF-47AA-A10F-342A2E328DF9"
src="https://github.com/user-attachments/assets/bcbe4876-f9a7-497a-b288-460087a65546"
/> |
## To test
Form behaviour (in particular URL validation) on:
- Webhook endpoint
- Log drains
- Cron jobs
- Database hooks
## 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
## What kind of change does this PR introduce?
Chore that resolves DEPR-399.
## What is the current behavior?
The cron jobs table in Studio uses a fixed-width `Name` column, which
can truncate long job titles and make them hard to read on
`/project/:ref/integrations/cron/jobs`.
## What is the new behavior?
The cron jobs table now allows resizing the informational columns,
including `Name`, `Schedule`, `Last run`, `Next run`, and `Command`,
while keeping the `Active` and `Actions` columns fixed-width.
This also gives the `Name` column a sensible minimum width so it can be
resized without collapsing.
## Additional context
Adds a small regression test around the cron jobs column configuration
to verify that:
- informational columns are resizable
- utility columns remain fixed
- the `Name` column has a non-zero minimum width
## Context
Adds a source filter for the query performance advisor so you can filter
out queries from the dashboard, or not from the dashboard
<img width="309" height="217" alt="image"
src="https://github.com/user-attachments/assets/c1fab9af-e57e-482f-afdb-d77a6600edb3"
/>
For transparency how this works:
- Queries fired via the dashboard through the /query endpoint get
enriched with metadata from the API to include a comment like `--
source: dashboard`
- That's mainly how this filter works atm, to check if this comment
exists if the source "Dashboard" is selected, and the inverse if the
source "Non dashboard" is selected
This PR:
* Adds an upgrade flow to the stripe sync engine, allowing users to
upgrade to the latest version when it becomes available.
* When a new version of sync engine becomes available, users will see an
upgrade button instead of install button.
* Bumps `supabase-management-js` to version 2.0.2 and
`stripe-experiment-sync` to version 1.0.27.
* Uses `parseSchemaComment` and related logic from the
`stripe-experiment-sync` package in order to avoid writing duplicate
code in supabase ui.
* Allows installation/uninstallation to timeout after 5 minutes to avoid
these operations from getting stuck in case an error occurs in their
processing. This allows users to retry the operation, as opposed to the
older behaviour where the users always see a spinner on the
install/uninstall button and couldn't do anything.
* Remove the SSL enforcement admonition as it is no longer required.
Sync engine can now be installed with or without SSL enforcement
enabled.
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
## Context
Resolves FE-2794
Just addressing some friction points i ran into when setting up MFA for
my account under account preferences
## Changes involved
- Hitting enter at each step of setting up MFA will submit and proceed
(Previously didn't, had to click buttons)
- When logging in with MFA, automatically submit after entering 6 digits
- Refactored to use react hook form for `AddNewFactorModal` in
`FirstStep` and `SecondStep` + simplified the logic a little
## What kind of change does this PR introduce?
Feature / UX update.
## What is the current behavior?
Platform webhook deliveries cannot be retried from the deliveries table
or the delivery details sheet.
## What is the new behavior?
- Adds a retry action to individual platform webhook deliveries in the
endpoint deliveries table
- Adds a retry action to the shared delivery details sheet footer
- Limits retry to non-success deliveries
- Applies the table action hit area guidance from the design system
Successful deliveries should also not expose retry in this mock flow.
## Additional context
- Addresses DEPR-340.
- In the current mock implementation, queueing updates the existing
delivery in place: it sets the status to `pending`, clears
`responseCode`, and refreshes `attemptAt` to the current timestamp.
- The mock does not create a separate queued job or append a new
delivery record yet; the same delivery is resurfaced at the top of the
list because deliveries are sorted by latest attempt time.
Fixes#42357
Supersedes #42364
## Problem
When copying the URL of a file that is not in the currently opened
folder, the folder path is still included in that file URL.
## Solution
We actually always have the file path, use it directly instead of
rebuilding it from the storage explorer state
## How to test
1. Create a bucket and upload a file in it
2. Create a folder and upload a file in it
While the folder is selected, right click the root file uploaded in 1
and copy its URL. It should not contain the folder name. Same with the
dropdown menu that appears when hovering the file.
Ensure the observability link in the sidebar and command menu are
properly guarded by IS_PLATFORM to prevent them from showing in
self-hosted or CLI environments.
The logic is functionally the same (IS_PLATFORM && reportsEnabled), but
restructured with IS_PLATFORM as the outer check for clarity, and added
comments explaining the platform-only restriction.
https://claude.ai/code/session_01PG2TEGaSxaXZfXkbSBU3kQ
## 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.
Co-authored-by: Claude <noreply@anthropic.com>
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
## Problem
- The schema visualiser lacks editing capabilities which leads to a lot
of navigation (ediing tables, columns)
- ReactFlow prevents users from selecting table and column names (to
copy them). Diasbling drag and pan on those texts would make moving
items cumbersome
- Long table and column names are hidden and even hide other elements
## Solution
- Add menus for both tables and columns
- Truncate long names with ellipsis and add a tooltip
- Hide menus when exporting to png/svg
[Screen Recording 2026-03-12 at
10.10.08.webm](https://github.com/user-attachments/assets/b2780266-e874-41d1-ac82-7c2c4ba5abf2)
## feat(sso): improve SSO management UX (safe deletion + invitation type
selection)
This PR improves the SSO management experience by introducing a safer
deletion flow for SSO providers and allowing explicit control over
invitation authentication type.
## SSO Provider Deletion Improvements
The SSO provider deletion flow has been redesigned to better communicate
the impact of the action and prevent accidental destructive operations.
### UX Improvements
* Replace `ConfirmationModal` with `TextConfirmModal` in `SSOConfig`
* Require typing the SSO domain to confirm deletion
* Display the number of organization members authenticating via SSO who
will be removed
* Add destructive visual styling and clear warnings about irreversible
consequences
* Update confirmation button label to emphasize impact:
* `I understand, delete SSO provider and members`
### Warning Content
The modal now clearly communicates:
* The domain being deleted
* That SSO authentication will be disabled
* That SSO-authenticated members will be permanently removed
* That those members must be re-invited to regain access
If SSO members exist, a highlighted destructive warning box shows:
```
X organization member(s) who authenticate via SSO will be permanently removed
```
### Implementation Details
* Add `useOrganizationMembersQuery` to fetch organization members
* Calculate SSO members by filtering `is_sso_user === true`
* Only display the member warning when the count > 0
* Modal uses `variant="destructive"` and `size="small"`
This pattern follows the existing **Delete organization** confirmation
flow.
### Initial Delete Support
This PR also introduces the underlying deletion functionality:
* Add `useSSOConfigDeleteMutation`
* Add delete button (trash icon, danger styling) in the SSO config
footer
* Layout mirrors `CustomDomainDelete` pattern:
* delete button on the left
* save/cancel actions on the right
* Success toast shown after deletion
* Form resets to explicit default values after deletion
## Invitation Type Selection
Organizations with SSO configured can now explicitly choose the
authentication method when inviting new members.
Previously, invitations always inherited the inviter's authentication
method. This made it difficult to support mixed authentication
organizations.
### New Invitation Options
When SSO is enabled, the invite dialog now shows an **Invitation type**
dropdown:
* **Automatic (based on your account)**
Default behavior; inherits authentication method from the inviter.
* **Require SSO authentication**
Sends an SSO invitation.
* **Email/password authentication**
Sends a non-SSO invitation.
### Implementation Details
* Add `useOrgSSOConfigQuery` to detect if SSO is configured
* Add `requireSso` field to the form schema with enum:
* `auto`
* `sso`
* `non-sso`
* Only display the dropdown when the organization has an SSO provider
* Transform form values before sending to the backend:
```
sso -> { requireSso: true }
non-sso -> { requireSso: false }
auto -> {} (omit parameter)
```
* Update `OrganizationCreateInvitationVariables` to include optional
`requireSso`
* Preserve backward compatibility by only sending the field when
explicitly set
## Bug Fixes
* Attribute mapping preset buttons (Azure, GSuite, Okta) now properly
mark the form as dirty so the save button becomes enabled
* Form reset after deletion now uses explicit default values instead of
the last saved state
## Problems Solved
This PR addresses several UX issues:
1. Deleting an SSO provider previously used a simple confirmation with
no explanation of impact
2. Users could not see how many members would be affected by deletion
3. The destructive and irreversible nature of the action was not
visually emphasized
4. Invitations always inherited the inviter's auth method
5. Organizations could not intentionally mix SSO and non-SSO users
## Types
TypeScript types in `api-types` were updated to support the new
`require_sso` parameter.
---------
Co-authored-by: Chris Stockton <chris.stockton@supabase.io>
Co-authored-by: Ali Waseem <waseema393@gmail.com>
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
(working with @charislam @awaseem on this one)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
Per
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md):
- ✅ `pnpm --filter studio build`
- ✅ `pnpm test:prettier`
- ✅ `pnpm format`
## What kind of change does this PR introduce?
Instruments `studio` app's table creation flow with Sentry.
## What is the current behavior?
The table creation flow isn't instrumented in detail, which means we
have less visibility into understanding performance problems or errors
within this specific flow.
## What is the new behavior?
The table creation flow is instrumented in detail. This instrumentation
allows for Sentry dashboards like this one (created based on locally
generated Supabase data), to help monitor anything going wrong with this
critical flow:
<img width="1915" height="1131" alt="image"
src="https://github.com/user-attachments/assets/e2c5380e-7b00-41c1-9109-3ee4e47ff63b"
/>
---------
Co-authored-by: Ali Waseem <waseema393@gmail.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?
As we now have the internal error code mapping in `shared-data`, thought
it better to move away from the GraphQL endpoint and leave that for
external use. The error code popovers in studio now rely on shared-data,
meaning instant loads and no rate limiting.
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`)
## Context
Small one - while on the database replication page, if you open the
Connect Dialog and change the "type" field, the destination panel opens
up. Happening cause the string for `useQueryState` conflicts here - both
are using `type`
Fix is just to update the string for `useQueryState` for the
DestinationPanel component, changed it to `destinationType`
## 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 introduces Query Insights. It's the first edition of possible
future updates. This takes our old prototype and builds upon it for a
more action driven insights view.
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Ali Waseem <waseema393@gmail.com>
### Summary
This PR adds a dismissable modal that prompts paid org users to fill in
their billing address. We need billing addresses for tax compliance and
the existing banner hasn't been as effective (~10k orgs still missing).
The modal shows on page load when all of these are true:
- ConfigCat flag `enableBillingAddressModal` is on
- Org is on a paid plan (not free)
- Org does not have billing address set
- Org is not partner-managed
- User has BILLING_WRITE permission on stripe.customer
The modal can be dismissed via the close button, but re-opens on every
page navigation.
Once the user saves a valid address, the organizations query is
invalidated and organization_missing_address flips to false - the modal
stops appearing permanently.
<img width="1256" height="703" alt="Screenshot 2026-03-05 at 4 22 11 PM"
src="https://github.com/user-attachments/assets/57e7d1b8-b3b6-4366-ad23-60910a0defe8"
/>
### Testing
#### Automated Tests
I've added unit tests in this PR
#### Manual testing
Manual test cases:
- Free org - modal does not appear
- Partner-managed org - modal does not appear
- User with "developer role" modal does not appear
- Configcat Flag disabled - modal does not appear
- Dismiss modal, navigate to another page - modal re-opens
- Fill form and save - modal closes and does not reappear
- API failure loading billing data - shows error state with Retry button
---------
Co-authored-by: Ignacio Dobronich <ignacio@dobronich.com>
## 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>
Stacked PR 4/5 for page title improvements. Includes account and
organization-level title updates plus organization list/selector page
titles.
_Base:
[dnywh/feat/page-titles](https://github.com/supabase/supabase/pull/43538)_
---
## What kind of change does this PR introduce?
- Resolves FE-1960
- Resolves FE-1983
- Resolves DEPR-207
## What is the current behavior?
Page titles between surfaces are inconsistent and vague. Sometimes they
say the product name:
```
My Project | My Org | Supabase
```
...even when on a specific surface like Database > Tables.
Other times they show the entity name but skip over the project or org
name :
```
Edge Functions | Supabase
```
## What is the new behavior?
Account and organization-level title updates plus organization
list/selector page titles, adopting the layout title format introduced
in https://github.com/supabase/supabase/pull/43538:
```
users | Table Editor | My Project | My Org | Supabase
hello-world | Logs | Edge Functions | My Project | My Org | Supabase
Backups | Database | My Project | My Org | Supabase
Authentication | My Project | My Org | Supabase
```
That format is:
entity, section, surface, project, org, brand
## Additional context
Related stacked PRs also based on the the original
[dnywh/feat/page-titles](https://github.com/supabase/supabase/pull/43538)
branch:
- https://github.com/supabase/supabase/pull/43534
- https://github.com/supabase/supabase/pull/43535
- https://github.com/supabase/supabase/pull/43537
---------
Co-authored-by: Joshen Lim <joshenlimek@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
## What kind of change does this PR introduce?
- Bring back the old home page for self hosted, because the new one does
not work for self hosted users
- Unit tests to catch this in the future
Fix `graphql_public` schema not showing in legacy exposed schemas
selector
## Summary
- The `graphql_public` schema was getting filtered out of the exposed
schemas multi-select when the API grant toggles feature flag is disabled
- `ExposedSchemaSelector` (new mode) already had an exception for
`graphql_public` – this just adds the same exception to the legacy
mode's schema filter
## Test plan
- [ ] Disable the `tableEditorApiAccessToggle` feature flag
- [ ] Go to Settings > API > exposed schemas
- [ ] Confirm `graphql_public` appears in the schema list and is
selectable