Commit Graph
151 Commits
Author SHA1 Message Date
Pamela Chia 99c6e306c7 fix(www): repair legacy reference redirects (#51059)
I repointed legacy reference redirects and first-party links to the
sections the Docs app currently serves. Old client and common-filter
URLs still targeted bare slugs, while SDK landing URLs targeted
`/start`. I preserved v1 auth destinations and linked the retired Dart
v0 migration guide to its original source.

## To test

On the www preview:
- [x] Request `/docs/client/order` with a crawler user agent. Expect a
redirect to `/docs/reference/javascript/using-modifiers-order`.
- [x] Request `/docs/common/filters/_sl` with a crawler user agent.
Expect a redirect to `/docs/reference/javascript/using-filters-rangelt`.
- [x] Request `/docs/reference/kotlin` with a crawler user agent. Expect
a redirect to `/docs/reference/kotlin/introduction`.
- [x] Open the Storage permissions section. Expect its bucket reference
link to target `/docs/reference/javascript/file-buckets-createbucket`.

## Linear
- fixes GROWTH-1293


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

## Summary by CodeRabbit

* **Documentation**
* Updated links across blog posts, product pages, and feature listings
to point to current JavaScript, Flutter, and Dart documentation.
* Updated legacy documentation redirects to current reference pages,
including filter, modifier, client, and authentication guides.
* Changed reference-root redirects to lead to each language’s
introduction page.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-29 20:48:03 -07:00
Pamela Chia 177ef0cdd6 fix(www): repair broken docs links and redirect /blog/rss.xml (#51002)
## Problem

Four www pages link to docs URLs that return 404:

- `/storage`: the "Learn more" links for analytics and vector buckets
(`storage/analytics-buckets`, `storage/vector-buckets`)
- `/` (frameworks grid): the Vue quickstart (`quickstarts/vuejs`)
- `/edge-functions`: the CI/CD link (`functions/cicd-workflow`; that
page was merged into the deploy guide)
- `/partners`: the Enterprise SSO link (`auth/sso`)

Feed readers also request `/blog/rss.xml`, which renders the blog 404,
while the feed lives at `/rss.xml`. Apart from prefetch requests, it is
the most-requested 404 on www.

## Solution

- Point each link at the live page: `storage/analytics/introduction`,
`storage/vector/introduction`, `quickstarts/vue`,
`functions/deploy#cicd-deployment`, `auth/enterprise-sso`.
- Redirect `/docs/guides/functions/cicd-workflow` to the deploy guide.
This also fixes the older blog post and changelog links to it. The
redirect destination has no anchor because the `.md` redirect generator
in `next.config.mjs` appends `.md` to the destination.
- Redirect `/blog/rss.xml` to `/rss.xml`.

## To test

On the www Vercel preview:
- [x] On `/storage`, click "Learn more" under analytics buckets and
vector buckets: expect the analytics and vector introduction pages. They
navigate to `/docs/guides/storage/analytics/introduction` and
`/docs/guides/storage/vector/introduction`. The www preview doesn't
serve `/docs`, so I confirmed every new docs target returns 200 on
production.
- [x] On `/`, click Vue in the frameworks grid: expect the Vue
quickstart. The Vue tab's "Read docs for Vue" link navigates to
`/docs/guides/getting-started/quickstarts/vue`.
- [x] On `/edge-functions`, click the CI/CD link: expect the deploy
guide scrolled to CI/CD deployment. Opens "Deploy to Production" in a
new tab with `#cicd-deployment` in view.
- [x] On `/partners`, click the Enterprise SSO link: expect the
enterprise SSO guide. Opens "Enterprise Single Sign-On" in a new tab.
- [x] Request `/blog/rss.xml` and
`/docs/guides/functions/cicd-workflow`: expect 308s to `/rss.xml` and
`/docs/guides/functions/deploy`. Both return 308, and `/rss.xml` serves
the feed as XML.
- [x] `/docs/guides/functions/cicd-workflow.md` returns 308 to
`/docs/guides/functions/deploy.md`.
- [x] None of the four pages still links to an old path
(`analytics-buckets`, `vector-buckets`, `quickstarts/vuejs`,
`functions/cicd-workflow`, `auth/sso`).

## Linear
- fixes GROWTH-1297


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

## Summary by CodeRabbit

* **Documentation**
* Updated quickstart and integration links for Vue, Edge Functions
CI/CD, analytics and vector storage buckets, and Enterprise SSO.
* Added permanent redirects from the old RSS feed and Functions CI/CD
guide URLs to their current locations.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-28 21:00:13 -07:00
Mert YEREKAPAN 2532fab239 feat(www): note that paid projects aren't paused for inactivity on pricing (#50986)
## Summary

Adds "Projects on paid plans aren't paused for inactivity" to the
pricing page's meta and Open Graph descriptions and to the generated
`pricing.md` intro. The existing copy is unchanged.

Ref: GROWTH-1191


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

* **Documentation**
* Updated pricing descriptions to clarify that projects on paid plans
are not paused for inactivity.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-28 19:33:07 +00:00
Mert YEREKAPAN 49da804baa feat(www): add database-only and agent guidance to homepage and pricing markdown (#50992)
## Problem

The markdown versions of the homepage (`/index.md`) and pricing page
(`/pricing.md`) don't say that a Supabase project can be used as a
standalone Postgres database, what that costs, or how an agent should
get set up. `llms.txt` also doesn't link to the product markdown pages.

Ref: GROWTH-1191

## Solution

Markdown only. No changes to the rendered HTML pages. All changes are
additive.

- **`/pricing.md`** (`apps/www/lib/llms.ts`): new "Database-only
projects" section covering Free and Pro costs for a single database
project and that paid-plan projects are not paused. Plan prices, the
Free database size, the Pro disk size, and the Free plan pausing note
are read from `packages/shared-data/plans.ts`, so they stay in sync.
- **`/index.md`**: short note for agents, a "Use it as just a Postgres
database" section, agent setup commands (agent skills, CLI), a
goal-to-docs table, and machine interfaces (MCP, OpenAPI, agent skills
index, llms.txt, markdown negotiation). One bullet added to Key
Differentiators.
- **`/llms.txt`**: new "Product overviews" section linking the product
markdown pages.

## Review instructions

1. Open `/index.md`, `/pricing.md`, and `/llms.txt` on the preview
deployment.
2. Check the new sections read correctly and the figures in
"Database-only projects" match the pricing page.
3. Every added link returns 200 as markdown, except
`https://mcp.supabase.com/mcp`, which requires OAuth.

## Checklist

Check all before review:

- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [x] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs
[style
guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide)


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

## Summary by CodeRabbit

* **Documentation**
* Added product overview links for Database, Auth, Storage, Realtime,
Edge Functions, Cron, Queues, and Vector, including a note about
Database’s Postgres compatibility.
* Expanded guidance on using Supabase as a standalone Postgres database,
optional product costs, Free-plan pausing, and database-only pricing.
* Added agent setup instructions, task-specific documentation links,
machine-readable endpoints, and a Markdown pricing link.
* Added database-only project details to generated pricing content,
including plan features, compute credits, pausing, and connection
guidance.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-28 19:16:14 +00:00
51a167d910 feat(www): partners landing page (#47874)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added a redesigned Partners page with partnership options, benefits,
application steps, FAQs, integration resources, and featured partners.
- Added an on-page partner application form with questions tailored to
the selected partnership type.
- Added a confirmation message with next steps and a link to the OAuth
integration guide.
- **Bug Fixes**
- Updated partner application links to open the form on the Partners
page.
  - Added support for checkbox-group fields in forms.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alan Daniel <stylesshjs@gmail.com>
Co-authored-by: Alex Hall <alex.hall@supabase.io>
Co-authored-by: Dion Zeneli <101271736+Dionysos288@users.noreply.github.com>
2026-09-25 15:53:32 +02:00
Mert YEREKAPAN 1f3f050573 feat(www): clarify database-only positioning on the database page (#50667)
## Summary

Clarifies on the database product page that a Supabase project can be
used as a standalone Postgres database, and mirrors the change in the
page's markdown version (`/database.md`).

Ref: GROWTH-1191

## Changes

- **Hero and page metadata**: adds "Use it on its own, or with the rest
of the Supabase platform."
- **Features section**: intro reframed around the database. The "Just
Postgres" card heading adds "standalone".
- **`content/md/database.md`**: same sentence in the tagline. New short
"Use it as a standalone database" section covering connecting, pooling,
pricing, and Free plan pausing. Client libraries marked optional. Pooler
naming updated to Supavisor. Links added for the connection guide and
`pricing.md`.

## Notes

- Pricing figures in the markdown mirror `packages/shared-data/plans.ts`
and are static here.
- The pausing statement matches
`docs/guides/platform/free-project-pausing`.


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

## Summary by CodeRabbit

- **Documentation**
- Clarified that Supabase projects include dedicated, standalone
Postgres databases.
- Explained that databases can be used independently or alongside the
Supabase platform.
- Added guidance on connections, pooling, pricing, pausing, and optional
client libraries.
- Identified Supavisor as the pooling service and added relevant
connection and pricing links.
- **Content**
- Updated database page messaging to highlight built-in security,
realtime subscriptions, auto-generated APIs, portability, and no vendor
lock-in.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-23 14:28:58 +00:00
Alaister YoungandAlaister Young 2f1ad03640 fix(www): prevent GitHub stars from falling back to zero (#50704)
The www build saves failed GitHub star requests as zero, which the
navigation displays as `0K`. This passes `GITHUB_TOKEN` through Turbo's
build environment and preserves a valid previously generated count when
a request fails.

If there is no valid previous count, the navigation displays “GitHub”
and the homepage contribution graphic omits the number. Cached fallback
is available only when the previous generated content exists; rate
limiting is a possible cause of the original failure, but has not been
confirmed from deployment logs.

## To test

- Run `pnpm --filter www exec vitest run
scripts/lib/githubStars.test.ts` — all 16 tests pass, covering
authenticated and anonymous requests, rate limiting, malformed
responses, and missing or invalid cached content.
- Build with a valid `GITHUB_TOKEN` and check that the navigation and
homepage graphic show the star count.
- Simulate a failed GitHub request with and without existing generated
content. Confirm that a valid previous count is retained, or that no
zero count appears when none is available.

Verified locally: live GitHub fetch through the new loader, Turbo dry
run with strict environment filtering and `GITHUB_TOKEN` allowed,
Prettier, and ESLint (one existing default-export warning). Full build
and browser checks have not been run.


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

## Summary by CodeRabbit

- **Bug Fixes**
- GitHub star counts are now displayed only when valid; otherwise, the
interface shows a clear fallback label.
- Star counts can fall back to cached data when GitHub is unavailable or
returns invalid results.
- Builds without GitHub data now complete gracefully instead of failing.

- **Tests**
- Added coverage for authenticated and unauthenticated requests, cached
fallbacks, invalid responses, and clean builds.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-09-22 18:04:14 +10:00
Danny White ec53175b8a refactor(ui): rename text-brand to text-primary (#50564)
## 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 -->
2026-09-22 16:19:03 +10:00
Danny WhiteandJoshen Lim a31ca2bad0 fix(ui): make brand text readable across themes (#49871)
## What kind of change does this PR introduce?

Bug fix and design-system update. Resolves DEPR-316.

Follow-up rename (`text-brand` → `text-primary`) is in a dedicated PR
(https://github.com/supabase/supabase/pull/50564) stacked on this one.

## What is the current behavior?

`text-brand` resolves to the canonical bright brand green in places that
need readable text, which fails WCAG AA on light surfaces. A separate
`text-brand-display` token adds another green for large type.

## What is the new behavior?

- `text-brand` maps to accessible `--primary` (light mode darkened to
meet ~4.5:1 AA)
- `--hue` / `--primary-hue` aligned to 157.5
- `text-brand-display` removed; former display callsites use
`text-brand`
- Bright fills/borders stay on `brand-default`
- Design-system colour and typography docs updated

| Before | After |
| --- | --- |
| <img width="514" height="112" alt="CleanShot 2026-09-02 at 11 13
09@2x"
src="https://github.com/user-attachments/assets/4e0138a9-a32d-4e4c-a426-90736706e1e7"
/> | <img width="512" height="138" alt="CleanShot 2026-09-21 at 11 42
05@2x"
src="https://github.com/user-attachments/assets/164cc5b1-a0c5-4e93-95f1-80016641a114"
/> |
| <img width="864" height="266" alt="CleanShot 2026-09-02 at 11 13
53@2x"
src="https://github.com/user-attachments/assets/3c1ca53f-bf9e-431e-bc15-816b4a275b8e"
/> | <img width="882" height="248" alt="CleanShot 2026-09-21 at 11 41
37@2x"
src="https://github.com/user-attachments/assets/24828e7b-ed6b-44cb-b9dc-becc3398bdfc"
/> |
| <img width="782" height="692" alt="CleanShot 2026-09-02 at 11 16
30@2x"
src="https://github.com/user-attachments/assets/fc871977-77bc-47fb-9e0e-9284e0ecd5cc"
/> | <img width="730" height="690" alt="CleanShot 2026-09-21 at 11 42
52@2x"
src="https://github.com/user-attachments/assets/bf479515-d5f9-471e-b82d-f097c0f4b56c"
/> |
| <img width="480" height="306" alt="CleanShot 2026-09-02 at 11 18
53@2x"
src="https://github.com/user-attachments/assets/03f341f4-f02e-44f8-a2b2-8c31670d0427"
/> | <img width="470" height="300" alt="CleanShot 2026-09-21 at 11 43
19@2x"
src="https://github.com/user-attachments/assets/9df18217-d5e6-48b8-ba0b-579d2664b94b"
/> |
| <img width="960" height="300" alt="CleanShot 2026-09-02 at 11 32
04@2x"
src="https://github.com/user-attachments/assets/6b1d9373-7a71-4247-81ff-26441604b09d"
/> | <img width="980" height="306" alt="CleanShot 2026-09-21 at 11 44
13@2x"
src="https://github.com/user-attachments/assets/41ad4784-02ec-4b29-b860-32af9fa79aa8"
/> |
| <img width="924" height="214" alt="CleanShot 2026-09-02 at 11 34
44@2x"
src="https://github.com/user-attachments/assets/1de661fe-c7b6-499b-a94f-e4737436ec79"
/> | <img width="752" height="162" alt="CleanShot 2026-09-21 at 11 44
56@2x"
src="https://github.com/user-attachments/assets/1811890f-0660-4445-84e9-447720954fa1"
/> |

## To test

Test each callsite **in light mode** (dark mode is largely unchanged).

### WWW

-
[Homepage](https://zone-www-dot-com-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/):
“Scale to millions” uses readable brand text (display token is gone)
-
[Careers](https://zone-www-dot-com-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/careers):
small “Careers” eyebrow readable; green dividers stay bright
`brand-default`
-
[Contact](https://zone-www-dot-com-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/contact-us):
email / policy links use readable brand text
-
[Regions](https://zone-www-dot-com-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/regions):
“Ask about early access to BYOC” readable

### Docs

- [Docs
homepage](https://docs-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/docs):
“DOCS” wordmark and resource links readable
- [Database
overview](https://docs-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/docs/guides/database/overview):
nav / footer brand links readable
- [JavaScript
reference](https://docs-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/docs/reference/javascript/introduction):
active sidebar treatment readable

### Design system

-
[Typography](https://design-system-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/docs/typography):
documents `text-brand` only (no display)
- [Colour
usage](https://design-system-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/docs/color-usage):
`text-brand` vs `bg-brand-default`
- [Design-system
homepage](https://design-system-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/):
brand text examples across themes

### Studio

- [Auth
providers](https://studio-staging-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/dashboard/project/_/auth/providers):
enabled provider badge text readable; status dot stays bright
- [Database
policies](https://studio-staging-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/dashboard/project/_/database/policies?new=true):
template hover text more legible
- [Database
connections](https://studio-staging-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/dashboard/project/_/observability/connections):
“Live” status readable; animated dot stays bright green

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-09-22 10:07:28 +10:00
Anthony Lio 819df2ae4d feat(www): menu nav enhancements (#50282)
## What kind of change does this PR introduce?

feature reworks the www header dropdowns

## What is the current behavior?

menu dropdown navigation animation between items feels scattered

## What is the new behavior?

- adds dropdown card resize with a transition and the content crossfades
when switching
- removes dead zone between or under nav items
- sets card is centered on the screen + enhance tablet bp
- adds slight ui refresh spacing, colors, sizes

| state | preview |
| -------|------|
| before | <video
src="https://github.com/user-attachments/assets/acd8e161-a697-4070-b751-4f4e9f1eab19"
/> |
| after | <video
src="https://github.com/user-attachments/assets/fe403afd-0074-4cb5-9223-fd6cdd2f7d5a"
/> |



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

* **New Features**
* Navigation dropdowns now provide smoother directional transitions,
keyboard-focus states, and reduced-motion support.
* Product navigation is organized into clearer Products and Modules
sections.
* Navigation layouts adapt earlier across screen sizes with responsive
two-column arrangements.

* **Style**
* Updated dropdown spacing, colors, borders, menu item styling, and
customer imagery sizing.
  * Refined blog loading placeholders with slightly tighter spacing.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-14 15:51:39 +03:00
Jordi Enric fb22534439 fix: share sentry crash policy and enable www reporting (#50232)
## Problem

The website initializes Sentry only on the server and edge runtimes,
leaving browser crashes unreported. Its crash-reporting setup also needs
the same consent and third-party filtering policy that docs and Studio
otherwise maintain separately.

## Fix

Add www browser initialization and tagged crash capture for both Next.js
routers, with accessible fallback focus. Move the shared
consent/platform and third-party filtering into common/sentry, reuse it
from all three apps, and remove the duplicated docs/www helpers and
tests. Preserve each app's initialization and Studio's additional noise
filtering, sampling, and sanitization.

Include the source-map upload token in www's build cache inputs, and
trigger the shared/www and Studio test workflows when the shared policy
changes.

## How to test

- Run `pnpm --filter www test ../../packages/common/sentry.test.ts
lib/sentry-capture.test.tsx`: all 22 shared-policy and real-SDK capture
tests passed locally.
- Run `pnpm --filter studio exec vitest run
lib/sentry-client-options.test.ts`: all 42 Studio options and
policy-parity tests passed locally.
- The www capture tests exercise the actual initializer and both router
handlers with an in-memory transport, verify crash tags and fallback
focus, and enforce consent. Removing initialization, capture calls,
boundary tags, or consent gating was verified to fail these tests.
- On a www preview with its DSN configured, accept telemetry consent and
trigger temporary render errors in both routers. Verify they reach the
www Sentry project with the boundary tag and readable stack traces.

Formatting passes. Full local app typechecks encounter existing
dependency/generated-file drift, with no diagnostics in changed files.
Three unchanged TanStack mock call-count tests fail locally and
reproduce against the pre-refactor implementation. Live Sentry ingestion
and source-map uploads remain deployment checks.


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

- **Accessibility**
- Error pages now automatically move focus to a clearly labeled error
message, helping screen-reader and keyboard users understand when a page
fails.

- **Reliability**
- Browser error reporting now captures application crashes more
consistently across supported page types and navigation transitions.
- Reporting respects consent and platform availability while filtering
unrelated third-party failures.

- **Testing**
- Expanded automated coverage for error capture, reporting rules,
consent handling, and accessible error-page behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-14 09:28:08 +02:00
Anthony Lio 42f1401769 fix(ui-patterns): a11y accessible names for ExpandableVideo (#50226)
## What kind of change does this PR introduce?

bug fix a11y `ExapndableVideo` 

## What is the current behavior?

`ExpandableVideo` blurred thumbnail has `alt="Video guide preview"`
sitting behind an overlay that already reads "Watch video guide" making
screen readers announcing the same thing twice

## What is the new behavior?

- adds an optional `videoTitle` prop that names the video once and feeds
both the button's `aria-label` and the player's `title`.

## Test
1. visit `/docs/guides/functions`

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

- **Enhancements**
  - Video previews in guides now display the relevant guide title.
  - Partner introduction videos now include a descriptive title.
- Video controls and embedded players provide more specific
accessibility labels when titles are available.
- Preview images without meaningful alternative text are treated as
decorative to reduce redundant screen-reader output.
- **Bug Fixes**
- Guide titles with Markdown formatting now appear as clean, readable
text in video labels.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-11 23:37:52 +03:00
Pamela Chia e315fbcb53 feat(www): emit sitemap lastmod from content dates (#50198)
I added content dates to `sitemap_www.xml` and `dateModified` to blog
JSON-LD so crawlers can compare freshness with page metadata. Both use
`updated` when present, otherwise the publication date.

**Changed:**
- **Consistent dates:** I use the same frontmatter parser for the blog
page and sitemap. It preserves authored dates across quoting and
timezones and rejects JavaScript frontmatter.
- **Invalid dates stop the build:** I reject impossible calendar days,
out-of-range times and offsets, malformed dates, and `updated` before
publication. Content changes run the generator in CI.
- **Authoring:** I documented optional `updated` for substantive
revisions. Events, static pages, and `/evals` omit `<lastmod>`.

**Note:** Changelog dates come from RSS. Existing sitemap omissions for
nonnumeric changelog slugs (GROWTH-1212) and app-router pages
(GROWTH-1214) remain separate.

## To test

On the preview:
- [x] Open `/sitemap_www.xml`: blog, alternatives, customer stories, and
included changelog entries should carry `YYYY-MM-DD` lastmod values.
Verified on the 2092513 preview: all 425 blog, 3 alternatives, 43
customer story, and 207 changelog entries carry a `YYYY-MM-DD` lastmod,
zero malformed values. Production currently emits no lastmod at all.
- [x] Inspect `/blog/supabase-is-now-available-in-gemini-enterprise`:
BlogPosting `dateModified` should be `2026-09-09`, matching its sitemap
entry. Verified: one BlogPosting block, `datePublished` and
`dateModified` both `2026-09-09`, sitemap lastmod `2026-09-09`.
- [x] Find the `/company` and event entries in the sitemap: neither
should carry lastmod. Verified: `/company` and all 13 `/events/` entries
have no lastmod.
- [x] Added: `/evals` and the `/changelog` index carry no lastmod
either.
- [x] Added: the blog page renders with no new console errors. The only
console error is a `/docs?_rsc=` prefetch 404: the preview host serves
404 for `/docs` itself, unrelated to this change.

## Linear
- fixes GROWTH-1206


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

- **New Features**
- Blog posts now support optional updated dates for substantive
revisions.
- Sitemap entries include accurate modification dates for blog,
alternatives, customers, and changelog content.
  - Blog structured data now includes the post’s modification date.

- **Bug Fixes**
- Improved validation prevents invalid or inconsistent content dates
from generating incorrect sitemap data.
- Changelog sitemap links are deduplicated and assigned their published
dates.

- **Documentation**
- Added guidance for specifying publication and update dates in blog
post metadata.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-11 17:20:53 +08:00
Pamela Chia c6a1c2052c feat(www): cross-list openapi and mcp endpoint (#50180)
`/.well-known/ard.json` advertises the Management API OpenAPI spec and
the MCP server, but `/llms.txt` listed neither and
`/.well-known/api-catalog` listed only the Management API. I added both
resources to the two surfaces that were missing them, so an agent finds
the same spec and endpoint whichever discovery file it reads first.

**Changed:**
- **llms.txt gains an `## API and agent resources` section**: two
described links, the same-origin `/openapi.json` spec and
`https://mcp.supabase.com/mcp`, from a small list in
`lib/agent-resources.ts`. A named heading rather than `## Optional`,
since llmstxt.org defines Optional as links an agent may skip. The
descriptions restate ard.json's on purpose; ard.json is curated to the
ARD schema and stays untouched.
- **api-catalog lists the MCP endpoint**: added as a catalog `item` plus
its own linkset member carrying `service-doc` (the MCP guide) and
`service-meta` (the OAuth protected-resource metadata the endpoint's 401
response already points at).
- **Tests cover what the two files advertise**: `ard-catalog.test.ts`
now parses api-catalog, checks that its `item` list and its anchored
members agree, and runs every same-origin URL from api-catalog and the
llms.txt resource list through the existing dead-URL resolver (public
file, app route, rewrite, or docs guide). The www tests workflow now
checks out `apps/docs/content/guides` (the directory the llms.txt route
already reads at runtime) and runs on changes to it, so moving a guide
that a catalog links to fails that PR rather than the next www one.

**Note:** `/openapi.json` is an external rewrite served uncached on
every request (338 KB). I tried `Cache-Control` and then the documented
`x-vercel-enable-rewrite-caching` + `CDN-Cache-Control` pair on that
path; the preview kept returning `x-vercel-cache: MISS`, so both are
reverted. Caching the alias is a separate change.

## To test

Tested on Vercel preview:
- [x] `curl -s <preview>/llms.txt | tail -5`: expect an `## API and
agent resources` heading followed by the OpenAPI spec link and the MCP
server link; the diff against production `llms.txt` is those appended
lines only
- [x] `curl -s <preview>/.well-known/api-catalog | jq '.linkset[2]'`:
expect a member anchored at `https://mcp.supabase.com/mcp` with
`service-doc` and `service-meta`, served as `application/linkset+json`

## Linear
- fixes GROWTH-1207


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

## Summary by CodeRabbit

- **New Features**
- Added API and agent resource links to `llms.txt`, including the
Management API specification and MCP server.
- Added the Supabase MCP server to the API catalog with service
documentation and metadata links.

- **Tests**
- Expanded catalog validation to cover API catalog entries, agent
resources, and documentation guide links.
  - Updated pull request checks to run when guide content changes.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-11 16:12:44 +08:00
Danny White 476d4a5851 refactor(ui): drop redundant Button variant="default" props (#50161)
## What kind of change does this PR introduce?

Mechanical cleanup on top of the Button default-variant change (#50160).

## What is the current behavior?

Many callsites still pass `variant="default"` even though that is now
the component default.

## What is the new behavior?

Removes redundant static `variant="default"` from legacy `Button` and
`ButtonTooltip` callsites. Keeps explicit defaults where they document
the API:

- `button-default.tsx` and `button-sizes.tsx` demos
- `DocsButton`, which pins neutral styling at the wrapper boundary

## To test

Studio:

- [Auth → Rate
Limits](https://studio-staging-2s957kwc4-supabase.vercel.app/dashboard/project/_/auth/rate-limits):
dirty the form so Cancel appears; Cancel stays neutral, Save stays green
- [Project Settings → API
Keys](https://studio-staging-2s957kwc4-supabase.vercel.app/dashboard/project/_/settings/api-keys):
`DocsButton` in the header actions stays neutral

Design system:

- [Design system →
Button](https://design-system-git-dnywh-dc924ac1-supabase.vercel.app/design-system/docs/components/button):
`button-default` / `button-sizes` still show explicit default styling;
Primary (green) is restricted to the Primary section (and `asChild`)

WWW:

- [www → Brand
assets](https://zone-www-dot-com-git-dnywh-dc924ac1-supabase.vercel.app/brand-assets):
Download logo kit / Download button kit stay neutral
2026-09-11 17:05:26 +10:00
Danny White 1131e3e2ce fix(ui): default Button variant to default instead of primary (#50160)
## What kind of change does this PR introduce?

Bug fix / design-system alignment for the legacy `Button` from `ui`.

## What is the current behavior?

Omitting `variant` on the legacy `Button` falls back to brand-green
`primary`. That makes accidental greens easy, and it is hard to spot the
real main action on busy pages.

## What is the new behavior?

- Legacy `Button` now defaults to neutral `default`
- Intentional primary CTAs (create, save, submit, marketing CTAs, and
matching `ButtonTooltip` usages) now set `variant="primary"` so their
appearance is unchanged
- Neutral actions that previously relied on the old fallback (cancel,
close, back, dashboard nav, and similar) become grey/white
- Design-system docs updated; regression tests cover the new default

`Button_Shadcn_` is unchanged. It already uses its own CVA default.

This is PR 1 of 2 in a stack. PR 2 drops now-redundant
`variant="default"` props.

## To test

Studio (http://localhost:8082):

- `/sign-in`: Sign in stays green
- Open a project → Database → Tables: New table stays green
- Auth → Users → Invite: Invite user stays green; Cancel / dismiss
controls stay neutral
- Project Settings → General: edit a field so Cancel and Save appear.
Cancel is neutral, Save is green

Design system (http://localhost:3003):

- Components → Button: default demo is neutral; primary demo is green;
featured preview is the default variant

Marketing (optional):

- www header: Start your project stays green; logged-in Dashboard is
neutral

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

- **Style**
- Buttons now default to a neutral style, while primary actions across
Studio, documentation, marketing pages, forms, dialogs, and error states
use prominent primary styling.
- Updated button examples and previews clarify the distinction between
default and primary variants.
  - Event registration now includes a directional arrow icon.

- **Tests**
- Added coverage confirming default button styling and explicit primary
styling behave as expected.
- Updated related test fixtures to use primary styling where
appropriate.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-10 11:23:17 +10:00
Danny White e4ea619251 fix(www): prevent State of Startups banner collision (#49932)
## What kind of change does this PR introduce?

Bug fix.

## What is the current behavior?

The Supabase Select 2026 announcement is rendered outside the fixed
navigation stack on `/state-of-startups`, so the navigation overlaps the
banner. At shorter viewport heights, the hero's viewport-based minimum
height also lets its headline sit beneath the fixed banner and
navigation.

## What is the new behavior?

On State of Startups routes, the announcement is rendered inside the
fixed navigation stack. The hero content also reserves the stack's
responsive height as its minimum top inset, keeping the headline clear
when the viewport is short without shifting it at normal heights.
Dismissing the banner moves the navigation back to the top without a
hard-coded navigation offset. Other routes keep the existing
announcement and sticky navigation layout.

| Before | After |
| --- | --- |
| <img width="1040" height="618" alt="State of Startups 2026 Supabase"
src="https://github.com/user-attachments/assets/2dc42574-1485-465c-93b1-6690e44a26e4"
/> | <img width="1040" height="618" alt="State of Startups 2026
Supabase"
src="https://github.com/user-attachments/assets/626374cf-8a6b-4519-bbcd-21acfc822fa0"
/> |

## To test

1. Open `/state-of-startups` on the deploy preview with the Supabase
Select 2026 announcement visible.
2. Confirm the announcement sits above the navigation without overlap at
desktop and mobile widths.
3. Reduce the viewport height to around 500px and confirm the State of
Startups headline remains below the navigation.
4. Dismiss the announcement and confirm the navigation moves to the top
of the viewport without leaving a gap.
5. Open another www route and confirm the announcement remains above the
sticky navigation.

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

* **Bug Fixes**
* Updated the announcement banner placement on State of Startups pages
so it appears within the sticky navigation area.
  * Preserved the existing announcement banner placement on other pages.
* Increased top spacing above the State of Startups header content
across mobile and desktop layouts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-03 15:22:55 +10:00
Pamela Chia 121332c1ac feat(www): add service json-ld to homepage (#49849)
Follow-up to #49768. Agent-readiness scanners grade schema breadth by
extended schema.org types (Service, FAQPage, Product);
SoftwareApplication alone doesn't register, so I added a Service block
whose offer catalog mirrors the products already rendered on the
homepage. I also brought `/.well-known/api-catalog` up to the RFC 9727
API-catalog profile.

**Changed:**
- **Homepage emits Service JSON-LD**: new `serviceSchema` builder in
`lib/json-ld.ts`; the offer catalog lists the six products the homepage
products section renders (Database, Authentication, Storage, Edge
Functions, Realtime, Vector).
- **api-catalog leads with the catalog context**: `linkset[0]` now
anchors the catalog URL and carries an `item` link to the Management API
base, per the RFC 9727 profile; the existing service-desc context moves
to `linkset[1]` unchanged.

## To test
Tested on Vercel preview:
- [ ] View source on the preview homepage: expect a fourth
`application/ld+json` script with `"@type":"Service"` and six offerings
- [ ] `curl <preview>/.well-known/api-catalog`: expect `linkset[0]` to
contain an `item` array pointing at `https://api.supabase.com/v1`

## Linear
- fixes GROWTH-1175


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

## Summary by CodeRabbit

* **New Features**
* Added structured service information to the home page, including
Supabase’s platform offerings.
  * Added an API catalog entry linking to the Supabase API endpoint.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-01 23:11:18 +08:00
Pamela Chia 3dddb60149 feat(www): publish agent discovery catalog and complete json-ld (#49768)
I added the agent-discovery surfaces the www app was missing: a resource
catalog at `/.well-known/ard.json` plus completed structured data on the
homepage. I scoped this from the agent-readiness gaps that are
truthfully closable on the www side; the catalog lists only resources
that already exist and serve 200 (MCP OAuth metadata, Management API
OpenAPI spec, llms.txt, agent-skills index).

**Changed:**
- **Agents can discover our machine-readable resources from one
document**: new static catalog at `/.well-known/ard.json` (Agentic
Resource Discovery format); the legacy `/.well-known/ai-catalog.json`
path serves the same file via rewrite, keeping a single source artifact.
- **Organization JSON-LD carries verifiable company details**: adds
`legalName`, a support `contactPoint`, and the registered address
already public on our Terms of Service.
- **Homepage declares the product as an application entity**: emits
`SoftwareApplication` JSON-LD via the existing
`softwareApplicationSchema` builder, same pattern as the vector module
page.

## To test
Tested on Vercel preview:
- [ ] `curl <preview-url>/.well-known/ard.json`: expect 200 with a JSON
catalog of 5 entries
- [ ] `curl <preview-url>/.well-known/ai-catalog.json`: expect the same
document with status 200 (rewrite, not a redirect)
- [ ] View homepage page source: expect three `application/ld+json`
scripts: Organization now includes `address` and `contactPoint`, and a
`SoftwareApplication` block is present

## Linear
- fixes GROWTH-1164



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

## Summary by CodeRabbit

- **New Features**
- Added an Agent Resource Description catalog listing Supabase’s MCP,
API, documentation, and agent skill resources.
- Added support for the legacy AI Catalog URL through a canonical
redirect.
- Enhanced website structured data with software application details,
legal information, support contact details, and business address.

- **Tests**
- Added validation ensuring discoverable `.well-known` resources are
cataloged and resolve correctly.

- **Chores**
- Updated marketing site test coverage for `.well-known` resource
changes.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-01 21:07:46 +08:00
Danny White 8439b0c77e fix(www): prevent Safari publicity logo clipping (#49742)
## What kind of change does this PR introduce?

Bug fix for
[DEPR-658](https://linear.app/supabase/issue/DEPR-658/fix-clipped-v0-and-langchain-logos-in-safari).

## What is the current behavior?

Inline publicity logos reuse the same SVG clip-path ID. Safari can
resolve v0 and LangChain against another logo's clipping rectangle,
causing the artwork to appear cropped or letterboxed.

## What is the new behavior?

Each publicity logo uses a namespaced clip-path ID. A focused regression
test verifies that SVG IDs are unique and every `url(#...)` reference
has a matching definition.

| Figure |
| --- |
| Before |
| <img width="2200" height="388" alt="CleanShot 2026-08-31 at 09 58
44@2x"
src="https://github.com/user-attachments/assets/99ef02e4-e436-4155-880a-6291364ea4cd"
/> |
| After |
| <img width="2196" height="370" alt="CleanShot 2026-08-31 at 09 58
00@2x"
src="https://github.com/user-attachments/assets/d36a9b83-737b-47f1-9f12-a110b3c82f23"
/> |

## To test

1. Open the deploy preview homepage in Safari.
2. Scroll to “Trusted by fast-growing companies worldwide”.
3. Confirm the v0 and LangChain logos are fully visible and the other
publicity logos are unchanged.
2026-08-31 10:12:33 +10:00
Pamela Chia 164de2c347 feat(www): markdown 404 for markdown-negotiated paths (#49596)
Nonexistent paths return a real 404 everywhere, but always with an HTML
body, even when the client asked for markdown via `Accept:
text/markdown` or a `.md` suffix. Middleware can't fix this: it gates on
a static slug allowlist and can't know a path will 404. I added two
`fallback` rewrites (`.md` suffix; Accept header containing
`text/markdown` or `text/*`) that run only after every route has failed
to match and route the request to a small `md-404` handler returning a
short markdown 404 pointing at /docs, /sitemap.xml, and /llms.txt. Real
pages are structurally unaffected.

**Note:** `lib/rewrites.js` is untouched (the plain rewrites array
became the `afterFiles` phase), so #49587 merges independently. I
updated next.config.test.ts's rewrites assertion for the phased shape;
it now also pins the two fallback rules.

## To test

I verified on the Vercel preview:
- [x] `curl -s -D - -H "Accept: text/markdown"
<preview>/definitely-not-a-page` (404, `Content-Type: text/markdown`,
body with the three pointers)
- [x] Same URL with a browser Accept header (existing HTML 404,
unchanged)
- [x] `curl -s -D - <preview>/definitely-not-a-page.md` (markdown 404)
- [x] `curl -s -D - -H "Accept: text/markdown" <preview>/auth` (200
markdown, unchanged) and `<preview>/support` (200 HTML, unchanged)
- [x] `/homepage.md` still 308s to `/index.md` (redirects phase wins);
`Accept: text/*` gets the markdown 404, matching real-page negotiation

Known boundary: `/changelog/<unknown>` keeps the HTML 404 body
(pages-router `fallback: 'blocking'` routes take priority over fallback
rewrites per Next docs); the status is still 404, verified on the
preview.

## Linear
- fixes GROWTH-1142


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

- **New Features**
- Added Markdown-formatted 404 responses for unmatched documentation and
`.md` page requests.
  - Included helpful documentation links in not-found responses.
- Requests that explicitly accept Markdown now receive a consistent
Markdown response.
- Added appropriate response headers for security, caching, and content
variation.

- **Bug Fixes**
- Improved routing for unmatched Markdown paths, ensuring they are
handled by the appropriate not-found response instead of returning an
unexpected format.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-27 13:29:04 +10:00
Pamela Chia 013af4ed58 feat(www): homepage json-ld, canonical, 404 links (#49533)
An agent-readiness scan of supabase.com (is-agentic.com, public report)
flagged that the homepage serves no structured data and no canonical tag
in raw HTML, and that the 404 page gives crawlers and agents no recovery
path. I fixed both.

**Changed:**
- **Homepage structured data**: the raw HTML now carries Organization
and WebSite JSON-LD plus `<link rel="canonical"
href="https://supabase.com">`. The schema builders already existed in
`lib/json-ld.ts` but were never wired to any page; this reuses the exact
inline-script pattern from the blog post pages. The canonical is
hardcoded to the production origin on purpose: `SITE_ORIGIN` resolves to
the branch URL on previews.
- **404 recovery links**: the 404 body now links to the docs, the
sitemap, and llms.txt, so a dead URL leads somewhere instead of a dead
end. The decorative giant "404" backdrop is a `div` instead of a second
`h1`, marked `aria-hidden`, and gets `pointer-events-none`: browser
testing showed the absolutely positioned backdrop was silently
swallowing clicks on the new links (positioned elements paint above
static siblings for hit-testing even when visually behind).
- **Drift-guard test**: `md-alternates.test.ts` asserted the literal
one-liner `alternates: mdAlternates('<slug>')`, which the canonical
wrapper breaks. I broadened the assertion to accept the spread shape
too; the rule it guards (every markdown-served slug advertises its `.md`
sibling) is unchanged and still enforced.

## To test
Tested locally against the dev server:
- [x] `curl -s localhost:3000` and parse the two `application/ld+json`
blocks: both valid JSON, types Organization and WebSite
- [x] `curl -s localhost:3000 | grep canonical`: expect `<link
rel="canonical" href="https://supabase.com"/>`, with the existing
`text/markdown` alternate link still present
- [x] `curl -s localhost:3000/some-nonexistent-page`: expect HTTP 404
with hrefs to `/docs`, `/sitemap.xml`, `/llms.txt` and exactly one
`<h1>` in the body

On the Vercel preview (verified via curl + Playwright browser run):
- [x] View source on the preview homepage: the two JSON-LD blocks
present and a canonical pointing at `https://supabase.com` (prod origin,
even on the preview host)
- [x] Open a nonexistent preview URL: 404 page renders the new link row
under the "Head back" button, visually unchanged otherwise (screenshots
in session records)
- [x] Added: click each recovery link: element hit-testing returns the
anchor for all three, and clicking Sitemap navigates to a valid
`/sitemap.xml` document (this check caught the pointer-events
regression, fixed in this PR)

## Linear
- Part of GROWTH-1124 (kept open: remaining scan findings are tracked in
a sub-issue)


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

- **SEO & Discoverability**
- Added canonical URL metadata and structured organization and website
information to the homepage.
- Improved 404 page navigation with links to Documentation, Sitemap, and
`llms.txt`.

- **Accessibility**
- Updated the 404 page’s decorative background marker to be
non-interactive and hidden from screen readers.
  - Added reduced-motion handling for page transitions.

- **Tests**
- Updated metadata validation to support multiple alternate metadata
configurations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-26 16:41:46 +08:00
claude[bot]andClaude 580af6e336 fix(www): stop blog tag and author breadcrumbs from becoming the page h1 (#49507)
<!-- ccr-slack-attribution -->
_Requested by **Pam Chia** · [Slack
thread](https://supabase.slack.com/archives/C07P3AU3J2D/p1787616624076769)_

**Before:** searching "supabase blog" on Google surfaces blog tag
sitelinks titled `Blog/Tags/Supabase` and `Blog/Tags/Community`, each
with the same snippet scraped from the footer newsletter form ("Get
product updates and news from Supabase").

**After:** those results use the route's real title, `Blog | Supabase`,
with a description specific to the tag, for example "Blog posts tagged
Supabase."

This change stops the visible breadcrumb on blog tag and author pages
from being the page's only `<h1>`, and gives tag and category pages
distinct meta descriptions.

## How this changes the Google result

The bad sitelinks come from two independent mechanisms, and each half of
this PR targets one of them:

**Titles.** Google prefers a page's `<h1>` over its `<title>` when the
two disagree, and on tag pages the only `<h1>` is the breadcrumb, whose
textContent is exactly `Blog/Tags/Supabase` (JSX strips the whitespace
between the children). Demoting the breadcrumb to a `<nav>` removes the
conflicting heading, so Google should fall back to the route's real
`<title>`:

- `Blog/Tags/Supabase` becomes `Blog | Supabase`
- `Blog/Tags/Community` becomes `Blog | Community`

**Snippets.** The "Get product updates and news from Supabase. Subscribe
..." text is not a meta description; it is Google's own synthesized
snippet, scraped from the footer newsletter form. Every tag and category
page shipped the byte-identical description "Latest news from the
Supabase team.", and Google discards a description duplicated across
many URLs. With a unique per-page description, Google has a usable
candidate again:

- tag rows should show `Blog posts tagged Supabase.` / `Blog posts
tagged Community.`
- category rows (`Blog | Engineering`, `Blog | Product`) already had
correct titles but the same scraped snippet; they should now show `Blog
posts in Engineering.` / `Blog posts in Product.`

Two caveats. Meta descriptions are suggestions, not directives, so
Google can still synthesize its own snippet; removing the
duplicate-description cause makes the supplied one much more likely to
win, but does not force it. And the replacement `<h1>` is the constant
sr-only `Supabase Blog` on every listing page: if Google again prefers
the h1 over the title, all sitelinks would read `Supabase Blog`. A
page-specific heading ("Posts tagged Supabase", "Posts by <author>")
would eliminate that residual risk and is a candidate follow-up.

Neither change appears in search results until Google recrawls and
reprocesses these URLs (see Additional context; the tag routes are
absent from the sitemap, which slows this). Requesting reindexing of a
few of these URLs in Search Console would speed it up.

## 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?

Bug fix (SEO / accessibility), `apps/www` only.

## What is the current behavior?

Two separate defects feed the same bad search result.

Google prefers a page's `<h1>` over its `<title>` when the two disagree,
and on tag pages the only `<h1>` is the breadcrumb.
`apps/www/app/blog/tags/[tag]/TagClient.tsx:21-27` wraps `Blog` / `/` /
`Tags` / `/` / `<tag>` in an `<h1>`; JSX strips the whitespace between
those children, so the element's textContent is exactly
`Blog/Tags/Supabase`. The route's own `<title>` is already fine
(`apps/www/app/blog/tags/[tag]/page.tsx:26`).
`apps/www/app/blog/authors/[author]/AuthorClient.tsx:55-60` has the
identical defect. Category pages escape it because
`apps/www/app/blog/BlogLayoutShell.tsx:19` counts `/blog/categories/` as
a listing route and renders the sr-only `<h1>Supabase Blog</h1>` at line
23, while `CategoryClient.tsx` renders no `<h1>` of its own.

Separately, every tag and category page shipped the byte-identical
description `Latest news from the Supabase team.`
(`apps/www/app/blog/tags/[tag]/page.tsx:27`,
`apps/www/app/blog/categories/[category]/page.tsx:23`). Google discards
a description reused verbatim across many pages and generates its own
snippet, in this case from the footer newsletter copy at
`apps/www/components/Footer/index.tsx:179`.

## What is the new behavior?

- `BlogLayoutShell.tsx` — `isListingRoute` now covers `/blog/tags/` and
`/blog/authors/` alongside `/blog/categories/`, via a
`LISTING_ROUTE_PREFIXES` constant. Those routes now render the same
sr-only `<h1>Supabase Blog</h1>` category pages already had.
- `TagClient.tsx` and `AuthorClient.tsx` — the breadcrumb is now a `<nav
aria-label="Breadcrumb">` instead of an `<h1>`. Every existing
className, the `/` separator spans and their `px-2` padding are
unchanged. The `h1` element selector in
`apps/www/styles/globals.css:176-179` applies `font-heading font-medium
tracking-normal`, so those three utilities move onto the `nav` to keep
the rendering byte-identical. No visual change is intended; only the
element and its accessible role change.
- `tags/[tag]/page.tsx` and `categories/[category]/page.tsx` —
`generateMetadata` now returns `Blog posts tagged ${label}.` and `Blog
posts in ${label}.`, matching the shape the author route already uses
(`apps/www/app/blog/authors/[author]/page.tsx:37`). Both use `startCase`
from `apps/www/lib/helpers.tsx:75-81` rather than `capitalize`, so
`launch-week` reads "Launch Week" and matches the filter chip label at
`apps/www/components/Blog/BlogFilters.tsx:56-57`. Title and description
use the same label.

## Additional context

`apps/www` is owned by `@supabase/marketing` per
`.github/CODEOWNERS:13`, so marketing should review this.

Recovery is not immediate: Google has to recrawl these routes before the
corrected titles and descriptions show up in search results.

Noted follow-ups, deliberately out of scope here:

- `/blog/tags/*` and `/blog/authors/*` are absent from the generated
sitemap (`apps/www/internals/generate-sitemap.mjs`), which slows
discovery and recrawl.
- The page bodies still pass a `capitalize`-derived label to `TagClient`
and `CategoryClient`, so the visible tag breadcrumb reads "Launch week"
while the title now reads "Launch Week". Aligning the visible label
would be a rendered-text change, so it is left for a separate PR.
- `openGraph` metadata on these routes is untouched and still carries
the generic copy.

### How it was tested

Prettier passes on the five changed files with the repo config, in both
the default and the `SORT_IMPORTS=false` mode CI uses. Full typecheck
and lint could not be run in this environment (no `node_modules`); the
changes are type-trivial — a `string[]`.`some()` predicate, a JSX tag
swap, and two template literals over an existing exported
`startCase(string): string` helper — and the diff parses clean under
`tsc` with module resolution disabled. Worth a reviewer eyeballing the
tag and author pages side by side against production to confirm the
breadcrumb renders identically.


---
_Generated by [Claude
Code](https://claude.ai/code/session_0164goAzGTkGnoxzCKagJ3Hw)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-08-25 14:44:58 +08:00
Miranda LimonczenkoandClaude Opus 5 60f7903b52 fix(www): group the filter controls and announce the result count (#49410)
Closes FE-4251

## Problem

The filter sidebars are unstructured `div` nesting. Measured on a
preview:

* 9 checkboxes on `/features` and 13 on `/partners/catalog`, none inside
a `fieldset`, a `role="group"`, or any region.
* The `/features` "Filter by tags:" `h2` has no `id`, so nothing can
reference it as a group name.
* The only landmarks on `/features` are two `nav` elements, so the
filter panel is unreachable by landmark navigation.

A screen reader user meets a checkbox announced as "authentication,
checkbox" with nothing conveying that it filters features by tag.

Separately, both result counts update on every filter change with no
live region, so the outcome of toggling a filter is never announced.

## Solution

* Wrap each checkbox set in a labelled `role="group"`.
* Wrap each filter panel in an `aside` labelled "Filters".
* Add `aria-live="polite"` to both result counts.

The two pages name their group differently on purpose. `/features` uses
`aria-labelledby` pointing at the existing `h2`, so the visible heading
is the accessible name. `/partners/catalog` uses `aria-label`, because
`filtersPanel` renders into both the desktop sidebar and the mobile
sheet, so an `id` would appear twice in the DOM. That file already calls
out the duplicate-id hazard at line 152 as its reason for using wrapping
labels.

Chose `role="group"` over `fieldset` and `legend` to avoid resetting UA
styling in a styled sidebar.

The single self-hosted checkbox keeps its own label and needs no group.

## Manual testing

**/features**

1. Open
[/features](https://zone-www-dot-com-git-www-filter-groups-and-live-count-supabase.vercel.app/features)
with Screenreader.
2. Confirm the tag checkboxes report as a group named "Filter by tags:".
3. Confirm a "Filters" landmark appears in landmark navigation.
4. Tick a tag filter. The result count changes and is announced.

**/partners/catalog**

5. Open
[/partners/catalog](https://zone-www-dot-com-git-www-filter-groups-and-live-count-supabase.vercel.app/partners/catalog)
at a desktop width. The filter panel is `hidden md:block`, so the
landmark only exists at md and above.
6. Confirm the category checkboxes report as a group named "Categories".
7. Open the mobile filter sheet at a narrow width and confirm the group
is still named, with no duplicate ids.


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

## Summary by CodeRabbit

* **Accessibility Improvements**
* Improved screen reader navigation for partner catalog and feature
filters.
  * Added accessible labels and landmarks for filter sections.
  * Updated result counts to be announced when selections change.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 09:46:03 -07:00
Miranda LimonczenkoandClaude Opus 5 0243ad7cf1 fix(www): make the view toggles a radio group and fix the filter rows (#49346)
Closes FE-4227

> [!NOTE]
> Bottom of a stack. #49409 and #49410 sit on top of this one, so merge
this first.

## Problem

Five defects in the view toggles on `/features` and `/partners/catalog`,
plus one in the `/features` filter rows. All measured on a preview.

**Toggles**

| Defect | Evidence |
| -- | -- |
| No pointer cursor | Tailwind 4 Preflight no longer sets `cursor:
pointer` on buttons. 14 of 19 buttons on `/features` computed to
`default`. Anchors were unaffected, which is why it looked inconsistent
rather than total. |
| The selected toggle offered a pointer | It is a no-op, so the cursor
promised an action that does nothing. |
| The selected state was invisible in light mode | `bg-surface-300` and
`bg-surface-75` both resolve to pure white. Contrast ratio exactly
1.000. The light theme base lightness is `.995` and each surface step
adds `.024`, so every lighter step clamps at white. The only cue left
was icon colour. |
| Hover inverted the selection | Unselected hover is `bg-surface-200`, a
2.7% black overlay, while the selected state was white. Hovering the
wrong button made it look selected. |
| No grouping | Two unrelated buttons. Nothing conveyed one choice with
two options, and the selected view was not programmatically determinable
at all. |

**Filter rows on /features**

A pointer appeared only on the narrow gap between each checkbox and its
label:

| Element | Computed cursor |
| -- | -- |
| wrapper `div` | `pointer` |
| `label` | `default` |
| checkbox | `default` |

`cursor-pointer!` sat on the wrapper. A declaration targeting an element
always beats an inherited value, so `!important` on the parent changed
nothing and both children overrode it.

## Solution

**Toggles become a `ToggleGroup`** on both pages, replacing the raw
button pairs.

* `type="single"` renders `role="group"` with `role="radio"` and
`aria-checked` per item. That describes one choice with two options
rather than two independent toggles, so a screen reader announces the
selection and its position in the set.
* Each group gets an `aria-label`, which the existing `ToggleGroup`
usage on `/pricing` lacks.
* Selected item gets `cursor-default`, unselected gets `cursor-pointer`.
* Selected background becomes `bg-surface-400`, a 5.4% overlay that
clears the 2.7% unselected hover and removes the inversion.

**Filter rows** become wrapping `label` elements with `cursor-pointer`
directly on the label, matching `IntegrationsContent.tsx`. The whole row
becomes a click target, and `id` values derived from raw product names
go away.

`toggleVariants` sets the selected background to `bg-surface-300` under
both `data-[state=on]:` and `aria-checked:`, and twMerge only dedupes
matching prefixes. Both are overridden here so adopting the primitive
does not reintroduce the invisible state this PR fixes. The primitive
defect is FE-4245.

### Behaviour change

The toggle pair is now a single tab stop navigated with arrow keys,
rather than two separate tab stops. That is correct for a mutually
exclusive group, but it is a change from current behaviour.

### Related, deliberately not here

| Work | Where |
| -- | -- |
| Checkbox primitive pointer cursor | #49408, so the shared-package
change is reviewed separately. The checkbox itself still shows an arrow
on this branch. |
| Naming these toggles, which rely on `title` | FE-4229 |
| Base-layer cursor fix across www, Docs and Studio | FE-4228 |
| Sharing one component between the two pages | FE-4244 |

## Manual testing

1. Open
[/features](https://zone-www-dot-com-git-www-view-toggle-pointer-cursor-supabase.vercel.app/features)
in light mode. The selected toggle is visibly darker than the unselected
one.
2. Hover the selected toggle. The cursor is an arrow. Hover the
unselected one. It is a pointer, and it does not become darker than the
selected one.
3. Tab to the toggle pair. It takes one tab stop. Move between options
with the arrow keys.
4. Inspect either toggle. It has `role="radio"` with `aria-checked`
tracking the selection, and the wrapping group has an `aria-label`.
5. Hover a tag filter row over the label text and over the gap between
the checkbox and the text. Both show a pointer. The checkbox itself
still shows an arrow here; that is #49408.
6. Click a filter row well away from the checkbox. The filter toggles.
7. Repeat steps 1 to 4 on
[/partners/catalog](https://zone-www-dot-com-git-www-view-toggle-pointer-cursor-supabase.vercel.app/partners/catalog).

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 09:19:59 -07:00
Miranda LimonczenkoandClaude Opus 5 c79d7be7d9 fix(www): give the feature and partner card grids list semantics (#49411)
Closes FE-4252

## Problem

`/features` renders 79 feature cards as bare `Link` elements in a grid
`div`. Measured on a preview, `main` contains zero `ul`, `ol`, `li`, and
zero `role="list"`. `/partners/catalog` is the same.

A screen reader user gets a run of loose links with no "list, 79 items",
no set size, and no way to navigate by list. Sighted users see an
obvious grid of cards, and the structure conveying that is purely
visual.

Same defect class as FE-4101 and DOCS-1279, both already in this
milestone.

## Solution

Make each card container a `ul` with one `li` per card. Four containers:

| File | Container |
| -- | -- |
| `apps/www/pages/features.tsx` | feature card grid |
| `apps/www/app/partners/catalog/IntegrationsContent.tsx` | featured
partners grid |
| same | grid view |
| same | list view |

This change makes a Screenreader announce the number of items and track
them.

Most of this diff is re-indentation from the added wrapper.

## Manual testing

**/features**

1. Open
[/features](https://zone-www-dot-com-git-www-card-grid-list-semantics-supabase.vercel.app/features)
with Screenreader. Confirm the cards report as a list of 79 items, and
that the count tracks the filters.
2. Check the grid at mobile, tablet and desktop widths. Cards stay equal
height within a row and the column counts are unchanged.

**/partners/catalog**

3. Open
[/partners/catalog](https://zone-www-dot-com-git-www-card-grid-list-semantics-supabase.vercel.app/partners/catalog)
in grid view with Screenreader. Confirm both the featured section and
the main grid are lists.
4. Switch to [list
view](https://zone-www-dot-com-git-www-card-grid-list-semantics-supabase.vercel.app/partners/catalog?view=list).
Confirm it is a list and the dividing lines between rows are unchanged.

Compare any of these against
[production](https://supabase.com/features). The rendering should be
identical; only the markup changes.


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

## Summary by CodeRabbit

* **Accessibility**
* Improved semantic structure for partner catalog and feature cards
using properly organized lists.
* Expanded card links to make larger portions of featured and grid cards
clickable.
  * Preserved existing layouts, content, and filtering behavior.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 09:19:40 -07:00
Miranda LimonczenkoandClaude Opus 5 932180541e fix(ui-patterns): give the shared InfoTooltip trigger an accessible name (#49345)
Closes FE-4093

## Problem

The shared `InfoTooltip` trigger's only child is an SVG and it has no
accessible name, so a screen reader announces an unnamed button and the
information the tooltip carries is unreachable. `button-name`, critical.

`/pricing` renders 34 of them.

## Solution

* Add an optional `label` prop rendered as `sr-only` text, with a
generic fallback so the 22 call sites that pass nothing still get a
name. The prop is optional because 26 files import this component across
www, Studio, design-system and ui-patterns.
* Drop the redundant `role="button"` from a native button.
* Label the four www call sites. A shared fallback alone would leave
`/pricing` announcing 34 identical names, which passes axe and stays
unusable. The labels come from the feature title and plan already in
scope, so no pricing data changes.

Docs is unaffected. It has its own `InfoTooltip` at
`apps/docs/features/ui/InfoTooltip.tsx` and never imports the shared
one.

## Manual testing

1. Open
[/pricing](https://zone-www-dot-com-git-ui-patterns-infotooltip-ac-07e2ab-supabase.vercel.app/pricing)
using a Screenreader.
2. Tab through the comparison table. Each info tooltip announces its own
feature, for example "About Database size".
3. Tab to a plan-specific tooltip. It announces the feature and the
plan, for example "About Automatic backups on the pro plan".
4. Confirm the icons render unchanged and the tooltips still open on
hover and on focus.
5. Run axe on the page. `button-name` reports zero elements.
6. Open the [design system InfoTooltip
page](https://design-system-git-ui-patterns-infotooltip-acces-66ec02-supabase.vercel.app/design-system/docs/fragments/info-tooltip)
and confirm the demo still renders.


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

## Summary by CodeRabbit

* **Accessibility Improvements**
  * Added descriptive labels to pricing information tooltips.
* Improved screen reader context for compute estimates, features, and
plan-specific pricing.
  * Added a default “More information” label for unlabeled tooltips.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 09:14:12 -07:00
Danny White fdf33e72c4 fix(studio): clean up onboarding returnTo paths (#49283)
## What kind of change does this PR introduce?

Bug fix. Follow-up to #41041 and DEPR-318.

## What is the current behavior?

Marketing "Start your project" links go to `/dashboard`, which redirects
unauthenticated users to `/org` and sets `returnTo=/org`. That value
survives when they switch from sign-in to sign-up, so email verification
still lands on the org list instead of org creation.

## What is the new behavior?

- Sign-in's **Sign up** link rewrites `returnTo=/org` (and
`/organizations`) to `/new`
- Docs mobile menu, www homepage/product CTAs, and solution page CTAs
link to `/dashboard/sign-up` for guests
- Signed-in visitors get the dashboard URL instead, so they never hit
the sign-up form
- Shared `DASHBOARD_SIGN_UP_URL` / `getDashboardCtaHref` helpers for www

Stacked on #41041.

## To test

Stacked on #41041. The studio preview below includes both PRs. www and
docs have their own previews.

### Studio: sign-in → sign-up rewrite

Using the [studio-staging
preview](https://studio-staging-git-dnywh-fixonboarding-return-to-supabase.vercel.app/)
from Vercel checks:

1. Open the preview while logged out. It should land on
`/dashboard/sign-in?returnTo=%2Forg`
2. Click **Sign up**. Expect the URL to include `returnTo=%2Fnew`

### Optional: www CTAs

Using the [www
preview](https://zone-www-dot-com-git-dnywh-fixonboarding-return-to-supabase.vercel.app/):

3. Logged out: homepage, product, or solutions **Start your project**
should go to `/dashboard/sign-up`
4. Logged in: the same CTAs should go to `/dashboard` (not sign-up)
(thought this will be hard if not impossible to test on staging)

### Optional: docs CTAs

Using the [docs
preview](https://docs-git-dnywh-fixonboarding-return-to-supabase.vercel.app/):

5. On mobile nav while logged out, click **Start your project**. Expect
`/dashboard/sign-up`

### Compare on supabase.green

Optional. Just to show what happens currently on `master`:

6. Open **supabase.green** while logged out, then click **Sign up** from
`/dashboard/sign-in?returnTo=%2Forg`. `returnTo` should stay as `/org`

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

## Summary by CodeRabbit

* **New Features**
* Start-project and sign-up links now direct visitors to registration
while signed-in users continue to reach the dashboard.
* Homepage, product, solution, and mobile navigation CTAs now provide
consistent authentication-aware destinations.
* Sign-up links preserve return destinations and existing navigation
parameters.

* **Bug Fixes**
* Corrected mobile navigation and marketing CTA links that previously
sent visitors to the dashboard root instead of the appropriate sign-up
flow.


<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-24 17:32:56 +10:00
Pamela Chia 21a27eeb4f feat(www): canonicalize homepage markdown at /index.md (#49384)
The www root markdown lived at an accidental URL: `/.md` served the
homepage markdown only because middleware strips the `.md` suffix and
the empty slug fell through to the homepage allowlist entry, while the
canonical-looking `/index.md` 404'd. The served markdown also opened
with stale legacy positioning copy that no longer matches the site. I
renamed the homepage content slug to `index` end-to-end so `/index.md`
is the one canonical markdown URL.

**Changed:**
- **`/index.md` serves the homepage markdown (200 `text/markdown`)**:
`content/md/homepage.md` renamed to `index.md`; the middleware bare-root
slug mapping, the generator's sort special-case, and the homepage
alternate tag follow, so the tag now advertises `/index.md`.
- **Legacy aliases 308 to the canonical URL**: `/.md`, `/homepage.md`,
and bare `/index` redirect via `lib/redirects.js`; `/llms/homepage.txt`
retargeted straight to `/index.md` to avoid a redirect chain. New
`next.config.test.ts` assertions pin all four.
- **Positioning refreshed**: the markdown now opens with "Supabase is
the Postgres development platform" (matching the site title), replacing
the outdated tagline.
- **Generator safety**: the redirect-exclusion filter in
`generateMdContent.mjs` now exempts the `index` slug (its HTML page is
`/`, not `/index`, so a `/index` redirect never refers to it), and the
build fails if `content/md/index.md` ever goes missing while middleware
still maps `/` to the `index` slug.
- **CI actually runs the new assertions**: I widened the `www-tests.yml`
paths filter to include `apps/www/lib/**/*.js`,
`apps/www/content/md/**`, and `apps/www/scripts/**/*.mjs`. It previously
only matched `.ts*` and the next.config files, so a PR touching only
`lib/redirects.js`, the markdown content, or the generator would skip
the tests that pin these redirects.

**Note:** the existing homepage alternate tag still exists, re-pointed
to the canonical URL. Whether the homepage should advertise a markdown
sibling at all is a separate decision; leaving it aimed at a 308 would
break tag consumers. Positioning wording is editorial, happy to tweak.

## To test
Tested on Vercel preview:
- [x] `curl -si <preview>/index.md`: expect 200 `content-type:
text/markdown`, body opens with the Postgres development platform
positioning and no longer contains the old tagline
- [x] `curl -sI <preview>/.md`: expect 308 with `location: /index.md`
- [x] `curl -sI <preview>/homepage.md` and `curl -sI
<preview>/llms/homepage.txt`: expect 308 with `location: /index.md`
- [x] `curl -sI <preview>/index`: expect 308 with `location: /`
- [x] `curl -s -H "Accept: text/markdown" -o /dev/null -w "%{http_code}
%{content_type}" <preview>/`: expect `200 text/markdown` (bare-URL
negotiation unchanged)
- [x] `curl -s <preview>/ | grep -o 'type="text/markdown"
href="[^"]*"'`: expect href ending `/index.md`

## Linear
- fixes GROWTH-1117



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

## Summary by CodeRabbit

- **New Features**
- Added support for `/index.md` as the canonical Markdown representation
of the homepage.
- Added permanent redirects for legacy homepage Markdown and text URLs.
  - Added `/index` to `/` redirect handling.

- **Bug Fixes**
- Updated homepage metadata, alternate links, Markdown negotiation, and
content generation to consistently use the new canonical path.
  - Improved homepage content description.

- **Tests**
- Expanded coverage for homepage Markdown routes, redirects, and URL
matching.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-24 15:19:56 +08:00
Pamela Chia 10c425ad0b feat(www): markdown copy/ask affordances (#48475) 2026-08-21 08:51:11 +08:00
Etienne Stalmans 18dc7e971d chore: update vendor DepthFirst (#49093) 2026-08-14 14:27:44 +08:00
claude[bot]andClaude c30437a58a fix: use shared favicon metadata so the tab icon isn't blurry on hi-dpi (#48770)
<!-- ccr-slack-attribution -->
_Requested by **Matt Rossman, Ali Waseem** · [Slack
thread](https://supabase.slack.com/archives/C0161K73J1J/p1785960993618839?thread_ts=1785960993.618839&cid=C0161K73J1J)_

## 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?

Bug fix.

## What is the current behavior?

The Supabase logo in the browser tab looks blurry on high-DPI displays
on supabase.com, but sharp on the dashboard. Same logo, same asset files
— only the marketing site looks soft.

Separately, `genFaviconData()` points one of its `<link rel="icon">`
tags at `favicon-128x128.png`, a file that no app in the repo ships.
That is a live 404 on docs, learn and ui-library today — and on
design-system, which hardcodes its own copy of the same icon list.

## What is the new behavior?

The tab icon is sharp on both, and the 404 is gone everywhere.

## Additional context

**How.** `apps/www/app/layout.tsx` hardcoded a Next.js `metadata.icons`
block that pointed `icon`, `shortcut` and `apple` all at
`/favicon/favicon.ico`. That `.ico` contains a single 16x16 layer, so on
a 2x display the browser has no 32px candidate to choose and upscales
the 16x16 — hence the blur. It only affects App Router routes, which now
includes the homepage, `/blog`, `/pricing` and the product pages; www's
remaining Pages Router routes already went through the shared component
and were fine.

www was not using the shared `genFaviconData()` helper from
`common/MetaFavicons/app-router`, which docs, learn and ui-library all
do. Swapping it in makes www advertise the same 16/32/48/96/128/180/196
PNG ladder the dashboard does, so the browser picks the 32px PNG on a 2x
display. The argument is `''` because www serves from the site root
(`basePath: ''` in `next.config.mjs`).

**Second, related change.** `packages/common/MetaFavicons/app-router.ts`
referenced `favicon-128x128.png`; the asset is `favicon-128.png` in
every app's `public/favicon/` (the pages-router variant of the helper
already had it right). Fixed to match. Without this, wiring www up to
the helper would have added a fourth app to the existing 404.

**Third, related change.** `apps/design-system/app/layout.tsx` had its
own inline copy of `genFaviconData` — byte-identical to the shared one
except that it still pointed at `favicon-128x128.png`, so fixing the
shared helper alone would have left design-system 404ing. Replaced the
91-line inline copy with the shared import, passing the app's existing
`BASE_PATH` (which mirrors `basePath` in its `next.config.mjs`) the same
way docs, learn and ui-library do. That removes the last hardcoded icon
list among the App Router apps, so the filename can't drift back out of
sync.

No favicon image assets were added or changed — every file the helper
references already exists in both `apps/www/public/favicon/` and
`apps/design-system/public/favicon/`.

**Possible follow-up.** `favicon.ico` itself is single-layer 16x16 in
both www and studio (byte-identical files). Regenerating it as a
multi-resolution ICO with 16/32/48 layers would help any consumer that
only reads the `.ico` — bookmark bars, some browser surfaces, and
notably supabase.com/evals, which is a rewrite to a separate Vercel app
and so won't pick up this layout change, but does resolve root-relative
icon hrefs against www's `public/`. Left out here because it touches
studio's assets too and is a separate call.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01F2AZs625JxKASYVAj8LWYq)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-08-14 10:55:49 +08:00
Shane c23f94cda3 Update homepage customer stories (#48955)
## 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?

Update to customer stories section on www

## What is the current behavior?

Please link any relevant issues here.

## What is the new behavior?

<img width="1021" height="691" alt="Screenshot 2026-08-11 at 3 23 03 PM"
src="https://github.com/user-attachments/assets/ee44f874-1cdf-47d6-bb63-6cdd8f85563a"
/>
<img width="1016" height="661" alt="Screenshot 2026-08-11 at 3 23 09 PM"
src="https://github.com/user-attachments/assets/97e84189-4351-489f-831f-f938a461e1dd"
/>
<img width="1011" height="661" alt="Screenshot 2026-08-11 at 3 23 13 PM"
src="https://github.com/user-attachments/assets/48ebdb06-6d6d-4711-ae5e-31cd513b144b"
/>
<img width="1036" height="677" alt="Screenshot 2026-08-11 at 3 23 17 PM"
src="https://github.com/user-attachments/assets/576aae48-33a3-4fe0-bc71-e6a0e3342608"
/>
<img width="1025" height="690" alt="Screenshot 2026-08-11 at 3 23 20 PM"
src="https://github.com/user-attachments/assets/5b7616f7-e968-4cbf-bd18-67de73904f14"
/>

## Additional context

Add any other context or screenshots.


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

## Summary by CodeRabbit

* **Content Updates**
* Refreshed the customer stories section with new featured companies,
testimonials, icons, colors, and visual gradients.

* **Responsive Design**
* Updated the layout breakpoint to improve the transition between mobile
and desktop presentations.
* Improved icon rendering with optional scaling for better visual
balance.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-12 09:34:56 -05:00
Danny White 2e7a8a3362 chore(www): rename customer logo folders to on-dark and on-light (#48962)
## What kind of change does this PR introduce?

Chore: rename customer logo folders and document the theme contract. No
intended visual change, aside from Phoenix Energy whose two marks were
in the wrong folders.

## What is the current behavior?

Customer logos live at:

- `/images/customers/logos/{slug}.png` (`logo`, light mode)
- `/images/customers/logos/light/{slug}.png` (`logo_inverse`, dark mode)

`light/` actually means “use me on a dark background”.

## What is the new behavior?

Same assets, clearer paths:

- `/images/customers/logos/on-light/{slug}.png` → dark/black mark →
`logo` → light mode
- `/images/customers/logos/on-dark/{slug}.png` → light/white mark →
`logo_inverse` → dark mode

Icon chips stay at `/images/customers/logos/{slug}-icon.svg`. Old
`/images/customers/logos/light/*` URLs redirect to `on-dark`. www README
now has the contract.

# To test

Use the [www
preview](https://zone-www-dot-com-git-dnywh-chorecustomer-logo-o-0d7bc1-supabase.vercel.app).
Toggle light/dark from the site header on each page. Logos should stay
readable (no white-on-white or black-on-black).

1. [Customers
grid](https://zone-www-dot-com-git-dnywh-chorecustomer-logo-o-0d7bc1-supabase.vercel.app/customers)
— main `logo` / `logo_inverse` surface. Spot-check Juniver, Phoenix
Energy, and one other card.
2. [Phoenix Energy
story](https://zone-www-dot-com-git-dnywh-chorecustomer-logo-o-0d7bc1-supabase.vercel.app/customers/phoenix-energy)
— story header uses `logo` only (on-light, plus a dark-mode brightness
filter). We swapped this pair.
3.
[Homepage](https://zone-www-dot-com-git-dnywh-chorecustomer-logo-o-0d7bc1-supabase.vercel.app/)
— “How industry leaders…” section. Icon chips only (`*-icon.svg`); the
wordmark `logo` field is unused here.
4. [Solutions /
Agents](https://zone-www-dot-com-git-dnywh-chorecustomer-logo-o-0d7bc1-supabase.vercel.app/solutions/agents)
— Chatbase quote near the top shows both theme variants. Same pattern on
[/healthcare](https://zone-www-dot-com-git-dnywh-chorecustomer-logo-o-0d7bc1-supabase.vercel.app/solutions/healthcare),
[/finserv](https://zone-www-dot-com-git-dnywh-chorecustomer-logo-o-0d7bc1-supabase.vercel.app/solutions/finserv),
and
[/b2b-saas](https://zone-www-dot-com-git-dnywh-chorecustomer-logo-o-0d7bc1-supabase.vercel.app/solutions/b2b-saas).
5. [Contact
sales](https://zone-www-dot-com-git-dnywh-chorecustomer-logo-o-0d7bc1-supabase.vercel.app/contact/sales)
— Good Tape / Xendit / Chatbase wordmarks (`on-light`). Same logos on
the demo form at
[/solutions/enterprise](https://zone-www-dot-com-git-dnywh-chorecustomer-logo-o-0d7bc1-supabase.vercel.app/solutions/enterprise).
6.
[Enterprise](https://zone-www-dot-com-git-dnywh-chorecustomer-logo-o-0d7bc1-supabase.vercel.app/solutions/enterprise)
— Mozilla / Epsilon3 / Pebblely icons in the use-cases section
(`on-dark`).
7.
[Vector](https://zone-www-dot-com-git-dnywh-chorecustomer-logo-o-0d7bc1-supabase.vercel.app/modules/vector)
— customer quotes. This is the only page that builds `on-light` /
`on-dark` paths at runtime from the customer slug.
8. [Mobbin
event](https://zone-www-dot-com-git-dnywh-chorecustomer-logo-o-0d7bc1-supabase.vercel.app/events/migrating-from-firebase-mobbin)
— company logo uses event `logo` / `logo_light` (dark vs light).
Optional second:
[/events/scale-to-millions-goodtape-auth](https://zone-www-dot-com-git-dnywh-chorecustomer-logo-o-0d7bc1-supabase.vercel.app/events/scale-to-millions-goodtape-auth).

Quick extra: hover **Product** in the site nav. The customer story
thumbnail uses `imgUrl` (`on-light`).

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

## Documentation
- Clarified customer logo requirements, including separate light and
dark asset locations, monochrome formats, and dark PNG assets for image
generation.

## Updates
- Standardized customer logos across stories, events, sales pages,
solution pages, testimonials, and generated images.
- Improved logo rendering across light and dark themes with dedicated
variants.
- Added permanent redirects for legacy logo URLs while preserving
filename suffixes.

## Tests
- Added coverage verifying legacy logo redirects resolve correctly,
including supported exceptions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-12 03:49:21 +00:00
AnaandAna 3fdaf14b4e chore(www): update Edge Functions customer quote to eXp Realty (#48667)
## 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?

- Updates the customer testimonial on the Edge Functions product page

## What is the current behavior?

The Edge Functions page shows an older customer quote.

## What is the new behavior?

- The quote is from Seth Siegler, Chief Innovation Officer at eXp Realty
- The quote is taken verbatim from the published eXp Realty customer
story
- The attribution links to /customers/exprealty
- Uses the existing seth-siegler.jpg avatar already in the repo; no new
assets

## Additional context

N/A


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

## Summary by CodeRabbit

* **Content Updates**
* Updated the Edge Functions customer testimonial with a new quote,
customer attribution, profile image, role, and link.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Ana <ana1337x@users.noreply.github.com>
2026-08-04 13:58:46 +07:00
Jonathan Summers-Muir 009528c6ca chore: update Lovable homepage logo (#48536)
## Summary

- replace the outdated Lovable homepage logo
2026-07-31 11:58:34 +00:00
Danny White 37dded67d1 feat: unify SkipToContent across studio, docs, www, and design-system (#48314)
## What kind of change does this PR introduce?

Feature / a11y polish

## What is the current behavior?

Studio and Docs each had their own skip-to-content link (different
styling and behaviour). www and design-system had none.

## What is the new behavior?

Shared `SkipToContent` in `ui-patterns`, adopted by Studio, Docs, www,
and design-system. Documented as a fragment with a short note under
Accessibility → Jumping ahead.

Tab once to reveal the button (top-left), Enter to jump to a
content-only `<main>`.

| After |
| --- |
| <img width="836" height="324" alt="CleanShot 2026-07-24 at 14 08
47@2x"
src="https://github.com/user-attachments/assets/6df29452-e53a-4eca-8f64-946f2b9f605d"
/> |

## To test

Shared steps for every app: enable Tab key navigation if needed, load
the preview, press **Tab** once — skip button should slide in top-left.
Press **Enter** — focus jumps to main content (no blue ring on
`<main>`). Press **Tab** again — first interactive control in the page
body, not the sidebar/nav. Hover the skip button — solid fill, clear
hover state, no chrome showing through.

- **Studio** —
[preview](https://studio-staging-git-dnywh-featskip-to-content-supabase.vercel.app)
→ sign in → any project page
- **Docs** —
[preview](https://docs-git-dnywh-featskip-to-content-supabase.vercel.app)
→ any docs page with sidebar
- **www** —
[preview](https://zone-www-dot-com-git-dnywh-featskip-to-content-supabase.vercel.app)
→ homepage or any marketing page with the default nav
- **Design system** —
[preview](https://design-system-git-dnywh-featskip-to-content-supabase.vercel.app)
→ any docs page (confirm Tab from content does **not** walk the
sidebar), plus [Skip to Content
fragment](https://design-system-git-dnywh-featskip-to-content-supabase.vercel.app/docs/fragments/skip-to-content)

## Additional context

Follow-up to #47694 / #48303 (Studio) and #47515 (Docs).

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

- **New Features**
- Added a reusable “Skip to content” accessibility link across key
layouts and pages.
- Updated main landmarks to support keyboard focus and skip-link
navigation (`id="main"`).
- **Accessibility**
- Skip links now follow consistent landmark-target conventions and
remain hidden until focused.
- Improved documentation for skip links/jump shortcuts in persistent
chrome layouts.
- **Documentation**
- Added a dedicated Skip to Content fragment, navigation entry, and
expanded accessibility guidance.
  - Updated button description wording in component docs.
- **Tests**
  - Added component tests for SkipToContent.
- **Chores**
  - Exposed SkipToContent via additional public package entry points.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-29 06:21:50 +10:00
Alaister YoungandAlaister Young ca2b50a0a7 chore(ui-patterns): collapse the admonition shim into ui-patterns/Admonition (#48377)
Follow-up to #48344: collapses the two resolution paths for the
Admonition module into one.

`src/admonition.tsx` was a back-compat shim re-exporting
`src/Admonition/`. Two ways to resolve one module is exactly what
produced the macOS self-import bug fixed in #48344, and the local
typecheck errors that #48374 worked around. This removes the shim and
standardizes on the PascalCase subpath, matching every other export in
the package.

**Changed:**

- Codemodded all 246 `ui-patterns/admonition` imports to
`ui-patterns/Admonition` (240 `.tsx`, 5 `.mdx`, 1 `.ts` across studio,
docs, www, design-system, and lite-studio)
- Pointed the 5 internal `'../admonition'` imports back at the
`'../Admonition'` directory

**Removed:**

- `packages/ui-patterns/src/admonition.tsx`, and its `./admonition`
entry in the exports map (regenerated with `pnpm gen:exports`)

## To test

- `grep -r "ui-patterns/admonition" --include='*.ts*'` → no hits
- `pnpm test:case-hazards` → passes
- `pnpm typecheck` → all 15 tasks green
- `pnpm --filter studio run lint:ratchet` → passes
- `pnpm --filter ui-patterns vitest run src/Admonition` → 11 tests pass

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

## Summary by CodeRabbit

* **Bug Fixes**
* Standardized Admonition component imports across the application and
documentation.
* Improved compatibility with case-sensitive environments by using the
canonical component path.
  * Removed the legacy Admonition import entry point.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-07-29 00:48:56 +08:00
Pamela Chia 9113c2ba04 feat: markdown alternate tags + llms.txt cleanup (#48287)
The June/July marketing redesign (#47271, #47228) rebuilt the homepage
and product pages off the Pages Router, silently dropping their `<link
rel="alternate" type="text/markdown">` head tags, and llms-full.txt has
been accidentally embedding every blog/customer/event page via an
`MD_CONTENT` spread. I restored the tags behind a shared helper, added a
CI drift test so a future redesign can't drop them silently again, and
trimmed both llms files to the agreed docs-index shape.

**Changed:**

- **Markdown siblings advertised again**: homepage, the 5 product pages,
pricing, and blog emit absolute `.md` alternate URLs via a new
`mdAlternates(slug)` helper (the one documented consumer of the tag
parses it from `<head>` and fetches the `.md` sibling, so tags must
point at the sibling, never the page itself).
- **Drift test**: a vitest file walks `content/md/**` and asserts every
markdown-served slug's page wires the helper (or is covered by the Pages
Router `_app.tsx` mechanism, whose alternate-link wiring the test also
asserts directly so removing it fails CI too). Source-level assertions
by design: page modules can't be imported under www's vitest config.
Fails correctly when wiring is removed (verified by hiding a page and by
altering the `_app.tsx` tag).
- **Vector orphan fixed**: `content/md/vector.md` moved to
`modules/vector` matching the live route (the page previously had no
negotiation or tag, and `/modules/vector.md` 404'd); `/vector.md` now
308s to `/modules/vector.md` and the legacy `/llms/vector.txt` redirect
no longer chains.
- **llms.txt + llms-full.txt**: the `## Product Overview` sections are
gone from both, each keeps a `## Pricing` section. This deletes the
hand-maintained links array (a drift trap) and fixes the accidental
~470-page embed, shrinking llms-full.txt from ~9.8MB to ~4.9MB and
dropping the 4.1MB generated content module from that route's serverless
bundle.

**Note:** this PR is scoped to apps/www only. The docs side
(troubleshooting pages and the rest of the docs surface) is handled
separately through a consolidated manifest-gated mechanism; an earlier
troubleshooting-tag commit was reverted out of this branch to keep the
scopes clean.

<details>
<summary>Why alternate tags matter (background)</summary>

Agents ingest markdown far more efficiently than our rendered HTML: a
fraction of the tokens and no extraction step. Since #47770 removed
UA-based serving (UA sniffing broke a major AI app's fetcher and
poisoned CDN caches), markdown is served only on explicit request: a
`.md` suffix URL, an `Accept: text/markdown` header, or llms.txt. That's
the right serving model, but it makes the markdown twin invisible to any
agent that doesn't already know our URL convention, and the major AI
fetchers send browser/wildcard Accept headers, so bare URLs hand them
HTML.

The `<link rel="alternate" type="text/markdown">` head tag is the
standards-based advertisement of the sibling. It has a documented
consumer today: an agent CLI that parses the tag from `<head>` and then
fetches the `.md` sibling, which is also why the tag must point at a
real sibling URL and never at the page itself. Peer docs sites ship this
tag as table stakes. These www pages used to carry it until the
June/July marketing redesign silently dropped it; the drift test in this
PR turns that regression class into a CI failure.

</details>

## To test

Tested locally (www + docs dev servers):
- [x] `/llms.txt` renders `## Documentation` + single-link `## Pricing`,
no Product Overview
- [x] `/llms-full.txt` renders `# Supabase` → `## Pricing` → `##
Documentation`, no Product Overview, ~4.9MB
- [x] Full www suite: 6 files / 71 tests green; drift test fails
correctly when a page is removed or the `_app.tsx` wiring is altered
- [x] `generateMdContent.mjs` emits `modules/vector`, bare `vector` slug
gone

On the Vercel preview (browser-verified with Playwright):
- [x] Alternate tag present on `/`, `/auth`, `/database`, `/storage`,
`/edge-functions`, `/realtime`, `/pricing`, and a blog post: exactly one
tag each, href = preview origin + `.md` sibling
- [x] `/vector.md` → 308 → `/modules/vector.md`, renders as markdown (`#
Supabase Vector`)
- [x] `/llms.txt` shows single-link `## Pricing`, no Product Overview
- [x] Coverage sweep: all 482 `MD_PAGES` slugs + changelog index/entry
curled on the preview; 471 pages carry exactly one tag, all `.md`
siblings 200 as `text/markdown`. The 11 misses are legacy blog slugs
whose HTML 308-redirects away (stale `MD_PAGES` entries predating this
PR, no head to tag; follow-up tracked in Linear)

Post-merge prod:
- [ ] Full llms.txt link sweep (every linked URL 200s; previews can't
cover the docs-hosted links)

## Linear

- fixes GROWTH-1013


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

## Summary by CodeRabbit

* **New Features**
* Added Markdown alternate links across key product, pricing, blog, and
troubleshooting pages.
* Added Supabase Vector documentation covering features, use cases,
workflows, and technical details.
* Updated AI-focused documentation indexes with dedicated pricing
content.
  * Added redirects for updated Vector documentation URLs.

* **Tests**
* Added coverage to verify Markdown documentation links stay aligned
with available pages.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-27 17:06:16 +08:00
Danny White 3bca21b3f8 chore(a11y): convert leftover focus recipes to focus-ring (#48219)
## What kind of change does this PR introduce?

Accessibility cleanup (DEPR-628).

## What is the current behavior?

Leftover call sites still use ad-hoc focus recipes
(`ring-foreground-muted`, `outline-brand`, Dialog/Sheet `focus:` rings,
etc.) instead of the shared utilities from #41575.

## What is the new behavior?

Converts those leftovers across `packages/ui`, Studio, www, docs, and
design-system to `focus-ring`, preferring `focus-visible`. Keeps
documented exceptions (`group-focus-visible`, InputGroup `:has()`).

## To test

Tab through controls (keyboard only). Expect a consistent offset ring on
`:focus-visible`, not a green/brand/custom stack, and no ring animation.

### www (marketing)

Preview:
https://zone-www-dot-com-git-danny-depr-628-focus-ring-fbccf9-supabase.vercel.app

- Global nav on `/`: Product, Developers, Solutions dropdowns; logo;
hamburger + mobile menu
- `/features`: view toggles and feature cards
- `/company`: card links
- `/changelog`: timeline / entry links
- `/partners/catalog`: grid/list toggle and partner cards
- `/pricing`: compute section expand control
- Product / Modules / Solutions sticky navs on product pages (e.g.
`/database`, `/storage`)
- `/state-of-startups`: TwoOptionToggle if present

### docs

Preview:
https://docs-git-danny-depr-628-focus-ring-long-tail-supabase.vercel.app

- Any guide page: top nav dropdowns and items
- Narrow viewport: hamburger, then mobile menu links + close
- Guide with PromptPanel / tabs: tab to prompt actions and tab list

### studio (dashboard)

Preview:
https://studio-staging-git-danny-depr-628-focus-ring-long-tail-supabase.vercel.app

- Project home: Connect section tiles; drag-handle focus on sortable
sections
- Integrations marketplace (`/project/<ref>/integrations`): featured
cards, list/grid toggle, list rows
- Auth (`/project/<ref>/auth/oauth-apps`,
`/project/<ref>/auth/providers`): open create/edit sheet, tab to close
(X)
- Database policies (`/project/<ref>/database/policies`): open policy
editor sheet, tab to close
- Storage policies (`/project/<ref>/storage/files/policies`): bucket
section links; policy modal close
- Query performance (`/project/<ref>/observability/query-performance`):
info icon buttons on metrics
- Replication pipeline detail (if available): slot lag / status info
icons
- Support (`/support/new`): attachment add/remove controls
- Table editor: spreadsheet import preview checkboxes; row text/JSON
editor TwoOptionToggle
- Any Dialog/Sheet/toast close (X): ring on keyboard focus only, not
mouse click

### design-system

Preview:
https://design-system-git-danny-depr-628-focus-ring-long-tail-supabase.vercel.app

- Colour palette swatches (keyboard focus)
- Form patterns sidepanel example: avatar / focusable control in the
example

## Additional context

- Linear: [DEPR-628](https://linear.app/supabase/issue/DEPR-628)
- Follow-ups: form-group CSS (DEPR-629), Storage columns selection
(DEPR-630), ESLint rule (DEPR-632)

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

* **Accessibility & Usability**
* Standardized keyboard focus indicators across navigation, dialogs,
forms, buttons, toggles, links, and tooltips using a consolidated focus
style.
* Improved toggle controls to use proper button semantics (instead of
clickable text), including `aria-pressed`/disabled handling and better
keyboard navigation.

* **Visual Updates**
* Harmonized hover/focus ring visuals across the design system, Studio,
documentation, and marketing pages while preserving existing layout and
interaction behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-23 08:52:22 +10:00
Danny White 6f6badae51 fix(eslint): promote require-explicit-tabindex to error (#48170)
## What kind of change does this PR introduce?

Accessibility / lint hardening (Safari keyboard focus).

## What is the current behavior?

`supabase/require-explicit-tabindex` is `'warn'`. Studio’s ratchet was
at 0 but the rule was still ratcheted; www / docs / design-system still
had raw `<button>` / `role="button"` call sites without an explicit
`tabIndex`.

[DEPR-627](https://linear.app/supabase/issue/DEPR-627) · follow-up to
#47984 / #48040

## What is the new behavior?

- Shared config: `'supabase/require-explicit-tabindex': 'error'`
- Swept www / docs / design-system (+ Studio test fixtures the ratchet
skipped)
- Removed the rule from the Studio ratchet + baselines

## To test

Prefer **Safari**. This PR only adds explicit `tabIndex` to raw
`<button>` / `role="button"` call sites — not links, and not controls
that already go through `Button` from `ui`.

### Marketing (`www`) ([staging
link](https://zone-www-dot-com-git-danny-depr-627-promote-req-7ae43c-supabase.vercel.app/))

- [x] Homepage frameworks / dashboard feature tabs — Tab through each
tab button
- [x] Product pages (e.g. `/auth`, `/database`) — section tab switchers
- [x] Narrow viewport — open the hamburger; Tab through menu buttons
- [x] `/partners/catalog` — filter / view controls
- [x] Blog view toggle (list ↔ grid)

### Docs ([staging
link](https://docs-git-danny-depr-627-promote-require-explici-25e46d-supabase.vercel.app/))

- [x] **Desktop (≥ lg):** top-right **⋯ menu** (hamburger icon) — opens
a dropdown that includes Theme. Not a separate theme button.
- [x] **Mobile (< lg):** top-right **hamburger** opens the sheet; close
(X) is the raw button we tagged. Theme inside the sheet uses
`ThemeToggle` / `DropdownMenuTrigger` from `ui` (already supposed to set
`tabIndex`).
- [x] **Code blocks** — copy / language controls
- [x] **Is this helpful?** — X / check are `Button` from `ui` (should
already Tab). After voting **while signed in**, the follow-up “What went
well?” / “How can we improve?” text button is the raw one we tagged.
- [x] **AI Tools → Copy as Markdown** (right rail on a guide) — this is
the only GuidesSidebar control this PR changed. “On this page” TOC items
are **links**, not covered by this lint.
- [x] **Reference docs** (e.g. JS client reference) — section headers
that expand/collapse in the left nav (`Collapsible.Trigger`)
- [x] **Troubleshooting index** — type in the search field, then Tab to
the **clear (X)** control

### Dashboard (`studio`)

No production UI changes in this PR (tests + lint config only). Quick
Safari smoke that prior tabindex work still holds:

- [x] Project sidebar — Tab through primary nav links
- [x] Settings → General — Tab through inputs / buttons
- [x] Storage → Files — Tab a bucket row / file actions
2026-07-23 05:21:15 +10:00
claude[bot]andClaude ffd5a93f37 feat(www): add hidden Legal Hub subprocessor list page (draft) (#48100)
<!-- ccr-slack-attribution -->
_Requested by **Nicole Kramer** · [Slack
thread](https://supabase.slack.com/archives/C0161K73J1J/p1783431374242039?thread_ts=1783431374.242039&cid=C0161K73J1J)_

## 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?

Feature (`apps/www`).

## What is the current behavior?

No public page for Supabase's subprocessor list, and no way for
customers to be notified when it changes.

## What is the new behavior?

A new hidden page at `/legal/customer-resources/subprocessor-list` shows
the current dated subprocessor PDF and lets anyone subscribe with their
name and email to receive an email whenever the list is updated. The
page is `noindex` and not linked from any nav, so it's shareable by
direct URL only for now. Mirrors Wiz's sub-processor-list page.

**How:**

- **Page**
`apps/www/pages/legal/customer-resources/subprocessor-list.tsx` —
pages-router, mirrors the existing Legal Hub pages (`DefaultLayout`,
`NextSeo`, `PageHeader` + breadcrumb, `SectionContainer` prose). Embeds
the PDF (inline preview + download link) and renders the subscribe form.
Marked `NextSeo` noindex/nofollow and intentionally left unlinked.
- A single `CURRENT_PDF` constant (filename + display date) is the only
thing to change when Legal hands over a new dated PDF.
- **Form** `apps/www/components/SubprocessorUpdatesForm.tsx` — mirrors
`SecurityNewsletterForm` (First name, Last name, Email; `ui`
primitives). Carries the framing copy verbatim, with **Subscribe to
updates** bold and Privacy Policy linked to
https://supabase.com/privacy.
- **API route**
`apps/www/app/api-v2/submit-form-subprocessor-updates/route.tsx` — exact
mirror of `submit-form-security-newsletter`; subscribes the user to the
Customer.io "Subprocessor Alerts" subscription (topic 4) via
`cio_subscription_preferences.topics.topic_4: true`.
- **PDF** `apps/www/public/legal/subprocessor-list/June-1-2026.pdf`.

**Updating the list in future:** Drop the new dated PDF into
`apps/www/public/legal/subprocessor-list/` and update the `CURRENT_PDF`
constant. Nothing else changes.

## Additional context

**Notes / to confirm:**

- Customer.io topic id `4` → `topic_4` (per Prashant); not independently
verified against Customer.io.
- Draft: page is intentionally unlinked and noindex until Legal signs
off.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01D9WS2QWQ8Y3o7PqDZabS3F)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-22 11:19:14 +01:00
Saxon Fletcher 74a0848ea5 Update logos on homepage (#48087)
Updates logos on homepage and removes slider
2026-07-20 15:02:53 +10:00
Francesco Sansalvadore 13330e6328 fix(ui): expandable video preview image (#47964)
## What kind of change does this PR introduce?

Restore preview image on ExpandableVideo trigger component.

## What is the current behavior?
<img width="1441" height="698" alt="Screenshot 2026-07-15 at 14 08 58"
src="https://github.com/user-attachments/assets/bdb1c4be-71a9-4601-b5c9-ab4fc97c48d1"
/>

<img width="1273" height="701" alt="Screenshot 2026-07-15 at 14 09 05"
src="https://github.com/user-attachments/assets/b8026bcc-3d43-4faa-873b-1745b32c166c"
/>

## What is the new behavior?
<img width="1434" height="678" alt="Screenshot 2026-07-15 at 14 08 53"
src="https://github.com/user-attachments/assets/8a3e64d1-5fe7-4ab9-a71b-3de5808d28b9"
/>

<img width="1160" height="672" alt="Screenshot 2026-07-15 at 14 08 48"
src="https://github.com/user-attachments/assets/db598a47-ed8e-435b-b3ef-8ae9e76761a2"
/>

---

Also fixed a border-b issue on the PartnerCatalogDetail.


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

## Summary by CodeRabbit

- **New Features**
  - Added thumbnail previews for partner catalog YouTube videos.
- Improved video preview presentation with clearer overlays and stronger
image blur.

- **Bug Fixes**
  - Updated image loading support for YouTube thumbnail URLs.
  - Refined sticky tab header spacing and alignment while scrolling.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-15 14:53:32 +02:00
d23f86021a feat(www): Partner Catalog update (#46757)
## Info architecture change around "Partners"

The www "integrations" now become more partner-driven.
`/partners/integrations` -> now Partner Catalog under
`/partners/catalog` (old links redirect to new paths)

Moved them close together in the nav dropdown and in the footer
<img width="494" height="336" alt="Screenshot 2026-07-09 at 11 06 41"
src="https://github.com/user-attachments/assets/a875fef0-0ab8-47ca-8756-d658b27c4892"
/>
<img width="1149" height="665" alt="Screenshot 2026-07-09 at 11 09 48"
src="https://github.com/user-attachments/assets/9631bb72-fe25-4fb4-b1af-9f14a37d02e7"
/>

## /partners 

This page remains untouched in this PR, updates to layout, content and
intake form are delegated to #47874

## /partners/catalog

Listed in the
[catalog](https://zone-www-dot-com-git-feat-www-partners-pages-supabase.vercel.app/partners/catalog)
are now partners. Some partners match with a listing.

<img width="1207" height="866" alt="Screenshot 2026-07-09 at 11 14 17"
src="https://github.com/user-attachments/assets/b65216be-976f-4ef5-91f8-1ad49da87b45"
/>

## /partners/catalog/[partner]

Each partner can have one or more "listings" which are either 
- simple guides
- foreign data wrappers
- dashboard integrations

Integrations available in the dashboard now all have a prominent
"Install integration" cta to open it in the dashboard [integrations
page](https://supabase.com/dashboard/project/_/integrations).

<img width="1269" height="776" alt="Screenshot 2026-07-09 at 11 16 51"
src="https://github.com/user-attachments/assets/3c7bb715-ffce-4d0a-905f-9a660c3b1f5a"
/>

## Docs

Update docs →
[Preview](https://docs-git-feat-www-partners-pages-supabase.vercel.app/docs/guides/integrations)
- remove "Supabase marketplace"
- use "Dashboard Integrations and Partner Catalog
- update integrations in sidenav to link to updated /partners/catalog/**
listings

<img width="1520" height="696" alt="Screenshot 2026-07-15 at 12 54 47"
src="https://github.com/user-attachments/assets/9f5a2794-4536-4299-97df-9732d3d75b4c"
/>

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

* **New Features**
* Added a Partner Catalog experience with search, category filters,
official-partner toggle, responsive filtering (sidebar + bottom sheet),
grid/list views, and featured partners.
* Added Partner Catalog detail pages with tabbed listings, MDX-rendered
content, image gallery with zoom overlay, and “add/install” actions.
* **Improvements**
* Updated “Become a Partner” layout and form support for prefilled
values and checkbox-group fields (including validation).
* Updated navigation/footer/docs and partner tile links to use Partner
Catalog routes; expanded redirects from legacy integrations paths.
  * Added public agent-skills discovery manifest.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alan Daniel <stylesshjs@gmail.com>
Co-authored-by: Alex Hall <alex.hall@supabase.io>
Co-authored-by: Miranda Limonczenko <miranda.limonczenko@supabase.io>
2026-07-15 11:10:51 +00:00
Pamela Chia 1b1b1ea0e0 chore: remove dead telemetry code (#47950)
## Summary
Removes two pieces of dead telemetry code found while root-causing the
docs pageview re-fire investigation (GROWTH-997, closed with no fix
needed). Pure deletion, 30 lines, no behavior change.

## Changes
- Delete `apps/www/app/ConsentWrapper.tsx`: an unwired third
`PageTelemetry` mount. www already mounts `PageTelemetry` in
`pages/_app.tsx` (Pages Router) and `app/providers.tsx` (App Router);
nothing imports this wrapper.
- Remove the exported `POSTHOG_URL` constant from
`apps/studio/lib/constants/index.ts`: zero consumers. The CSP allowlist
in `apps/studio/csp.ts` defines and uses its own local `POSTHOG_URL`,
which stays.

## Testing
Deadness verified before deletion, on current master:
- [x] Repo-wide grep for `ConsentWrapper`: only self-references inside
the deleted file
- [x] Repo-wide grep for `POSTHOG_URL`: remaining references are the
`csp.ts` local const only

## Linear
- fixes GROWTH-1002


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

## Summary by CodeRabbit

* **Bug Fixes**
* Removed an obsolete consent-related page wrapper to streamline page
behavior.
* Updated application configuration handling without changing existing
payment or usage settings.

* **Refactor**
* Simplified internal configuration and page composition while
preserving the existing user experience.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-15 12:01:29 +01:00
Francesco Sansalvadore 20cb05230b fix site_title (#47884)
Update www `site_title`.

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

## Summary by CodeRabbit

* **Documentation**
* Updated the site title and browser metadata to describe the product as
“The Postgres Development Platform.”

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-13 13:41:26 +00:00
Katerina Skroumpelou 373e917a99 feat(docs): generate server.txt reference and wire into www llms (#47782)
Add a `server` entry to the reference-markdown pipeline so it emits
`public/markdown/reference/server.md`, and register the Supabase Server
Library Reference as a source in the www `llms.txt` and `llms-full.txt`
routes.




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

* **Documentation**
* Added a new Supabase Server Library Reference covering server-side SDK
usage.
* Included the server reference in generated documentation and plaintext
documentation indexes.
* Made server SDK reference content available through the full
documentation feed.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-10 11:56:20 +01:00
Francesco Sansalvadore 532ac3638d fix(www): update customer logos from svg to pngs (#47777)
Some customer pages didn't show og-images properly because satori breaks
using svgs.

This PR replaces all customer logos from svgs to pngs. 
They're all exported at least 2x to 4x so image quality shouldn't get
worse anywhere.

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

## Summary by CodeRabbit

* **Bug Fixes**
* Updated several customer story pages and related listings to use PNG
logo assets, improving logo rendering consistency across the site.
* Refreshed the customer RSS feed metadata and removed a duplicate entry
so the feed stays up to date and cleaner.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-09 15:33:28 +02:00
Saxon FletcherandClaude Opus 4.8 fb02182e86 Color system (#47288)
## 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.


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

* **New Features**
* Refreshed theming across the UI to use modern color expressions and
shared theme variables (including OKLCH-based gradients), improving
consistency for charts, code blocks, overlays, icons, and decorative
backgrounds.
* **Bug Fixes**
* Improved light/dark color and gradient consistency across axis/grid
styling, reference lines, buttons/badges, sidebar accents, loaders, and
other visual components.
* **Documentation**
* Updated styling/theming guidance to align with the revised semantic
token system and the updated theme variable usage patterns.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 15:00:43 +10:00