## What kind of change does this PR introduce?
Refactor. Follow-up to #49871.
## What is the current behavior?
Branded (green) text still uses the `text-brand` classname while the
colour comes from `--primary`.
## What is the new behavior?
**Rename-only:** `text-brand` → `text-primary` across callsites and
docs. Leftover `bg-brand` / `border-brand` alias to `brand-default`. No
intentional colour changes in this PR.
This better matches how we treat our green in other components and
props, like `variant="primary"` for green buttons.
## To test
On light mode: smoke-test that branded text still looks like #49871
(readable green, not the bright fill).
-
[Homepage](https://zone-www-dot-com-git-dnywh-depr-316-text-brand-de2380-supabase.vercel.app/):
“Scale to millions” uses `text-primary`
- [Docs
homepage](https://docs-git-dnywh-depr-316-text-brand-to-primary-supabase.vercel.app/docs):
branded links like “More on self-hosting” are still readable
- [Typography
docs](https://design-system-git-dnywh-depr-316-text-brand-to-primary-supabase.vercel.app/design-system/docs/typography):
documents `text-primary`
- [Colour
usage](https://design-system-git-dnywh-depr-316-text-brand-to-primary-supabase.vercel.app/design-system/docs/color-usage):
`text-primary` is visibly darker than `bg-brand-default` _on light mode_
- [Studio auth
providers](https://studio-staging-git-dnywh-depr-316-text-brand-to-60fa6c-supabase.vercel.app/dashboard/project/_/auth/providers):
enabled provider badge text readable; status dot stays bright green
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Updated branded text, link hover states, icons, badges, indicators,
and highlighted content across the Design System, Docs, Studio, Learn,
UI Library, and marketing experiences to use the primary theme color.
* Updated syntax highlighting and table-of-contents styling for
consistent primary-color presentation.
* Refined brand color fallback behavior for bright fills and borders.
* **Documentation**
* Updated color-usage and typography guidance to recommend the primary
text utility.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
App-level fixes that reproduce on BOTH the Next and TanStack builds —
split out of #47657 (which stays TanStack-only) for reviewability. All
were found by a full-site click-through of the dashboard.
## Invalid HTML nesting (React 19 "will cause a hydration error" console
errors)
- **FormLayout description rendered in a `<p>`**
(`packages/ui-patterns`): consumers pass arbitrary JSX (the RowEditor's
`created_at` timezone note passes a `<div>` with `<p>`s) →
`<p>`-in-`<p>` / `<div>`-in-`<p>`. Container is now a `<div>` with
identical classes (Tailwind preflight makes them render the same).
- **Switch toggles nested inside Tooltip trigger buttons**
(button-in-button) in ColumnEditor ("Allow Nullable" + "Is Unique"),
ExtensionRow, and PublicationsTableItem → repo-standard `TooltipTrigger
asChild` + `<div>` wrapper.
- **Saved log queries rendered a `<div>` directly inside `<tbody>`**
(`/logs/explorer/saved`) → rows are now proper `<tr><td colSpan>`
wrappers; the component itself is untouched (it's valid in its sidebar
usage).
- **Nested anchors in observability metric cards**: a card-level
`<Link>` wrapped MetricCard's "More information" `<Link>` (identical
URLs) → the chevron affordance renders as a `<span>` when no `href` is
passed; clicks bubble to the card link, tooltips preserved.
Design-system standalone usage unaffected.
- **`objectFit="cover"` passed to modern `next/image`** on the featured
integration card (unknown-prop warning) — the className already had
`object-cover`; prop dropped.
## Ghost dead-snippet after deletion
Deleting the active SQL snippet left its id in `useDashboardHistory`
(`history.sql`), so the "SQL Editor" nav item navigated to
`/sql/<deleted-id>` — content fetch 404s, no editor pane renders, and a
phantom tab reappears. Fixed both ends: delete flows now purge dashboard
history (and the tabs store clears a stale `previewTabId`), and
`/sql/[id]` treats a snippet 404 as "clean up + `router.replace` to
`/sql/new` + toast" instead of rendering the dead state. Unit tests for
the store/history cleanup.
## `pg-meta` migrations query 400s on every project load
`ActivityStats` on project home runs the migrations list query, whose
SQL was a bare `select * from supabase_migrations.schema_migrations` —
that table only exists once a migration has run, so every other project
logged a failed `?key=migrations` request on every load (visible in
production consoles too). The SQL is now guarded with `to_regclass` +
`query_to_xml` (same pattern as the advisor lints' `storage.buckets`
guard), returning zero rows instead of erroring; legacy version-only
tables still work. Tested against real dockerized Postgres (absent
table, populated ordering, special chars, legacy schema) + MSW hook
tests.
Found and verified via /test-supabase-local (browser click-through +
console audit on both builds).
## To test
Console must stay free of React DOM-nesting errors ("cannot be a
descendant of" / "cannot contain a nested") on each surface:
1. Table editor → Insert row panel (`created_at` field renders its
timezone note) and Edit column panel ("Allow Nullable"/"Is Unique"
tooltips still hover).
2. `/database/extensions` and `/database/publications` → toggle switches
render, tooltips hover.
3. `/logs/explorer/saved` (with ≥1 saved query) → rows render full-width
inside the table, hover shows Actions.
4. `/observability` → no nested-anchor error on load; card body click
and the chevron both navigate; label help-icons still show tooltips.
5. `/integrations` → no `objectFit` unknown-prop warning; featured card
images still cover.
6. **Ghost snippet**: open a SQL snippet → delete it via the sidebar →
click the "SQL Editor" nav item → lands on `/sql/new` (no phantom tab,
no 404 content fetch). Direct-load `/sql/<random-uuid>` → toast +
redirect to `/sql/new`.
7. **Migrations 400**: load project home with a project that has never
run a migration → the `pg-meta/<ref>/query?key=migrations` request
returns **200** with `[]` (previously a 400 on every load). Database →
Migrations still lists real migrations when they exist.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Summary by CodeRabbit
* **Bug Fixes**
* Deleted SQL snippets are fully removed from dashboard history and
stale editor/tab state; users are redirected with a toast.
* Closing preview tabs no longer leaves stale references.
* Improved toggle/tooltip/dialog interactions to avoid broken UI,
including metric headers showing tooltips even without direct links.
* Migrations display safely when migration tables/relations are missing.
* **UI Improvements**
* Refreshed layout for saved queries, form descriptions, and integration
imagery.
* **Tests**
* Added coverage for snippet history cleanup, tab removal, migrations
SQL behavior, and query edge cases.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---
### Review feedback: `query_to_xml` breaks on Multigres (Ivan)
The defensive migrations query (added here to stop the `?key=migrations`
400 when the table doesn't exist yet) originally guarded with
`query_to_xml`, which is forbidden through Multigres's pooler (MUL-736 /
PSQL-1318). Rewritten without `query_to_xml`/`xmltable` using the
splinter#170 pattern: a PL/pgSQL `do` block guarded by `to_regclass`
(PL/pgSQL defers planning, so a missing table never errors) stashes the
rows into a transaction-local GUC via `set_config`, and a trailing
`select` reads them back with `jsonb_array_elements`. Verified that
postgres-meta sends the whole SQL as one simple-query string → single
implicit transaction → the local GUC survives to the `select` and
doesn't leak into the pooled connection. 6/6 dockerized-Postgres tests
(absent table → `[]`, populated/ordered/special-chars, legacy
version-only table, full pg-meta-shaped multi-statement string, GUC
non-leakage).
Note (out of scope, pre-existing):
`packages/pg-meta/src/sql/studio/advisor/lints.ts` still uses
`query_to_xml` — a separate pre-existing Multigres risk that should get
its own splinter-pattern sync.
---------
Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
Co-authored-by: Saxon Fletcher <saxonafletcher@gmail.com>
Introducing a new Integrations Marketplace layout
- behind feature flag
- behind opt-out feature preview (default to true) to easily toggle
before and after
Doesn't introduce new functionality, only layout change behind ff.
## What changed
Nothing if `marketplaceIntegrations` flag is off.
### With flag
- New Marketplace index layout
- filter via text or by `category`, `integration type` and `source`
- Featured Partners Integrations hero (hidden when any filter is active)
- toggle between `grid` and `list` view
- new integration detail page layout
- with top action bar
- more consistent fullWidth or narrow content layouts
- can access Feature Preview toggle under Account Dropdown > Feature
Previews > Marketplace
## How to review and what to test
I recommend reviewing file changes from bottom to top in
https://github.com/supabase/supabase/pull/45856/changes because it makes
more sense from a pr-logic perspective.
- [ ] Visit
https://studio-staging-git-chore-integrations-ui-refine-fs-supabase.vercel.app/dashboard/project/_/integrations
- [ ] Check if new layout doesn't have big layout issues like weird
paddings or margins mostly. (We can iterate in upcoming PRs for
additional features/fixes)
- [ ] Toggle "Marketplace" feature preview to `FALSE` and check that the
Integrations layout looks like in prod
https://supabase.com/dashboard/project/_/integrations
- [ ] Also check individual integration pages and toggle the feature
preview on and off to see before and after and check if everything looks
good
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Full Marketplace experience: explorer with featured hero,
filters/search, list & grid views, cards, sidebar, detailed integration
pages, install flows, badges, and a preview toggle.
* **Bug Fixes**
* Prevented stale markdown from showing when switching integrations.
* **Style**
* Improved responsive layouts, loading placeholders, and header/nav
full-width behavior.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45856)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Saxon Fletcher <saxonafletcher@gmail.com>
Co-authored-by: Raminder Singh <romi_ssk@yahoo.co.in>
This PR:
* Refactors integrations page implementation to make it simpler and
easier to understand.
* Integration category pages from marketplace db show category name and
description.
* Shows featured integrations coming from the marketplace db at the top
of the page.
* Hides empty categories:
https://linear.app/supabase/issue/INT-113/hide-empty-categories-on-dashboard-integrations-page
Below design related fixes will be done in a separate PR:
https://github.com/supabase/supabase/pull/45856. So this PR is ready to
merge with current fixes.
<details>
~~Design fixes needed after consulting with the design team:~~
- [ ] ~~Do not use inverted colors on images for featured integrations.
This leads to inconsistent images for the featured marketplace listings.
E.g. Grafana listing shown in the featured listings:~~
<img width="463" height="260" alt="image"
src="https://github.com/user-attachments/assets/76816807-667f-44b0-b68c-5e1ca342be1f"
/>
~~vs shown on it's own page:~~
<img width="909" height="667" alt="image"
src="https://github.com/user-attachments/assets/00efda48-3e4e-4b05-87ad-cbbce9047c94"
/>
- [ ] ~~The images on featured marketplace integrations should not be
truncated as seen in the first image above.~~
- [ ] ~~The **Install integration** button feels floating far out on the
right.~~
- [ ] ~~The description under the title is too long and truncated.
Requested by Doppler here:
https://supabase.slack.com/archives/C0AL11JG5MG/p1778009104728819?thread_ts=1777654129.027269&cid=C0AL11JG5MG~~
- [ ] ~~The content section doesn't render bulleted lists correctly.~~
</details>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Dedicated "Featured Integrations" section on the integrations page.
* Integrations can be marked as featured to appear in the featured
section.
* **Improvements**
* Sidebar shows only categories that contain integrations.
* Integration image handling improved for featured cards.
* Updated loading placeholders for integrations to provide a smoother
loading experience.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45507)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Saxon Fletcher <saxonafletcher@gmail.com>
This PR shows installed marketplace apps in the left pane on the
integrations page and shows the `Installed` badge on the card.
`Official` badge is not shown on marketplace listings.
<img width="1652" height="892" alt="image"
src="https://github.com/user-attachments/assets/16c0a218-1658-426e-9b5b-d28e44c5c3b6"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed excessive spacing on the integrations page
* Enhanced integration installation detection for improved accuracy
* **Style**
* Updated official badge display on integration cards
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
* Add shimmering-loader CSS to ui-patterns.
* Import the shimmering-loader classes from the ui-patterns component.
* Remove ShimmeringLoader from studio.
* Migrate studio to use ui-patterns/ShimmeringLoader.
* Migrate away from using default import for ShimmeringLoader.
* Fix the css imports in docs and studio.
* integrations refine
* refactoring
* integration page updates
* div
* clean up
* prettier
* Couple of minor refactors and fixes
* Fix missing base path for integration card image
* Fix editing a cron job in the previous job run tab, not updating the cron job details in the page header
* Cron job bread crumb to use job name instead of id if available, and add loading state for cron job subtitle
* Fixy fix
* Small fi
* ANother one
* Do not reroute after purging queue
* nit
* Final final final v3
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
* Replace all usage of useProjectContext with useSelectedProjectQuery
* Replace all usage of useSelectedProject with useSelectedProjectQuery
* Replace all usage of useProjectByRef with useProjectByRefQuery
* Replace all usage of useSelectedOrganization with useSelectedOrganizationQuery
* Deprecate useSelectedProject, useSelectedOrganization, and useProjectByRef hooks
* Deprecate ProjecContext
* Initial commit.
* Minor type fixes.
* Add a integration for Queues. Refactor some of the integration layout.
* Migrate the Cron integration to the new style.
* Add useInstalledIntegrations hook.
* Add an integration entry for vault.
* Add an integration entry for GraphiQL.
* Add supabase webhooks.
* Feat/integrations get layout (#30538)
* scroll based icon
* Update header.tsx
* remove dep from overview
* moar
* more table stuff
* moar
* alt nav put in
* fix MotionNumber issues
* more
* trying both layouts
* Fix bunch of type errors.
---------
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
* Migrate Vercel and Github files to their own folders.
* Switch all integrations with the new designs.
* More fixes for links, pages structure and other random stuff.
* Remove unneeded file.
* Another set of fixes. Migrated most of the extension integrations.
* Migrated Vault and webhooks to the new style.
* Various fixes to make the animation work.
* Remove extra code.
* Tiny fixes 😬 i swear its tiny
* Refactor IntegrationOverviewTab
* chore/ update integrations routes (#30585)
* init
* add child support in tabs
* add webhooks
* Update IntegrationPageHandler.tsx
* fix id issues
* use messageId instead
* animation tweaks
* Move the description to the wrappers array.
* The useInstalledIntegrations now provides integrations which could be installed.
* Add static content for the various integrations.
* Move the page handler logic into the integrations definitions.
* Clean up some extra code.
* Add logic to make the overview tab the default tab.
* Don't show the header until the integration id has been checked.
* Add logic to the integration pages to avoid weird loading bugs, deselecting tabs if the integration hasn't been installed etc.
* Fix the webhooks overview tab.
* Fix the buttons for enabling extensions.
* Add padding to all custom tab contents.
* Small fixes
* Prettier lint
* Fix icon color + add empty state for when available integrations are all installed
* Fix ts errors
* Fiox
* Add enable webhooks cta
* Fix key
* Fix all lints
* Fix the queues create sheet.
* Fix the deletion of wrappers.
* Fix the minimum version alert for the wrappers extension.
* Make the queues table fit the whole container.
* Fix an issue which reset the tab when installing an extension.
* Address comments
* Add loading state for installed integrations in side nav
* Fix edit secret not rendering value in input field after subsequent openings
* Fix vault keys auto filling search input with vault
* Fix search input placeholder for cron
* Minor fix in install database extension copy
* Fix a bad redirect when reloading.
* Fix bad url redirects.
* Fix scrolling in create new/edit wrapper sheet.
* Add y padding to the wrappers rows.
* Fix merge errors.
* More merge fixes.
* Fix bad imports during the merge.
---------
Co-authored-by: Jonathan Summers-Muir <MildTomato@users.noreply.github.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>