Commit Graph
5507 Commits
Author SHA1 Message Date
Wendie CheungandWendie Cheung ff5376c9f0 Add go page: Postgres Summit US 2026 contest (#49597)
## 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 — new marketing landing page (`/go` page).

## What is the current behavior?

No landing page exists yet for Supabase's presence at Postgres Summit US
2026 (Sept 30 - Oct 2, 2026, NYC).

## What is the new behavior?

Adds a contest landing page and thank-you page, modeled on the existing
`pgconf-dev-2026/contest` go page pattern:

- `supabase.com/go/postgres-summit-2026/contest` — MacBook Neo giveaway
entry page, featuring the "Everything to know about Postgres Locks" talk
by Brian Brennglass (Supabase), Wed Sept 30, 4:00–4:50 PM EDT, Rossi
Intermediate room
- `supabase.com/go/postgres-summit-2026/contest/thank-you` —
confirmation page after entry
- Registered both in `apps/www/_go/index.tsx` with a `// remove after
October 31, 2026` cleanup marker, since this is a temporary event page
- HubSpot form wired to a real form GUID, with field mapping verified
against the form's actual internal property names (note: `company_name`
maps to `name` on the HubSpot **Company** object, not the usual
`company` Contact property — verified directly in the HubSpot form
editor rather than assumed)

Verified locally: both pages render correctly (hero, speaker section
with headshot, how-to-enter steps, form) via `pnpm --filter www dev`.

## Additional context

- Contest entry deadline is currently set to Monday, October 12, 2026,
12:00 PM PDT — a placeholder estimate (~12 days post-event, matching the
pattern used on other event contest pages), not sourced from an official
deadline. Flagging for review before this goes live.
- No talk-slides link exists yet for this session, so the "View session
details" CTA links to the official postgresql.us session page instead.


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

* **New Features**
* Added a Postgres Summit US 2026 contest landing page featuring prize
information, event content, entry instructions, and a contest entry
form.
* Added a thank-you page with submission confirmation, contest details,
onboarding guidance, and links to the dashboard and website.
* Added registration for both pages with availability through October
31, 2026.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Wendie Cheung <wendie.cheung@supabase.io>
2026-08-26 21:42:10 +10:00
8291ed1401 Add Lingo.dev customer case study (#49595)
## 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?

Content: new customer case study for supabase.com/customers.

## What is the current behavior?

Lingo.dev doesn't have a case study on supabase.com/customers yet.
Source content: [Notion case study
doc](https://app.notion.com/p/supabase/Lingo-dev-3c05004b775f81e5a936dd40f77e2781)
(Linear:
[MARKET-1468](https://linear.app/supabase/issue/MARKET-1468/case-study-lingodev)).

## What is the new behavior?

- Adds `apps/www/_customers/lingo-dev.mdx`: how Lingo.dev runs retrieval
augmented localization on Supabase Database, Vector, Auth, and Storage,
and clears every enterprise security review (Mistral AI, Solana
Foundation, Veriff) without a database question raised.
- Registers the story in `apps/www/data/CustomerStories.ts` so it
surfaces on the customer stories listing.
- Adds logo (on-light/on-dark) and founder headshot assets for Max
Prilutskiy and Veronica Prilutskaya.

## Additional context

Ran through `supabase-writing` and `humanize` style passes before
finalizing copy.

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

* **New Content**
* Added a customer story highlighting Lingo.dev’s localization platform,
architecture, security practices, and operational results.
* Added the story to the customer stories collection with supporting
imagery, description, and call-to-action details.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Wendie Cheung <wendie.cheung@supabase.io>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 21:07:00 +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
Pamela Chia 6d4263bf1a fix(www): pricing table spacing and sticky offset (#49532)
Multi-line cells in the /pricing comparison table rendered as one
cramped block once lines wrapped: the stacked values had no gap between
entries, and the continuation lines' `leading-4` is a no-op at
`text-xs`. At the same narrow desktop widths (1024 to 1280px), category
headers clipped behind the sticky plan header because their hardcoded
`top-[108px] xl:top-[84px]` offsets desync from the plan header's
variable height.

**Changed:**
- **Value cells get vertical padding**: the value tds were `pl-6 pr-2`
with no vertical padding, so tall multi-line cells pressed text against
the row dividers; they now carry `py-5` like the row-label column (text
ink sits ~21px off both borders, measured).
- **Stacked price lines read as separate entries**: `gap-2` between
entries while wrapped lines inside one entry stay tight (`leading-4`),
so each price reads as its own block. Two earlier iterations that only
widened the entry gap (`gap-1`, then `gap-2` with looser `leading-5`
wraps) reviewed as still-cramped; the missing cell padding was the
dominant cause. Mobile untouched.
- **Category headers never clip behind the plan header**: a
ResizeObserver measures the sticky thead's real height and publishes
`--pricing-category-top` as a CSS variable on the table; the category
header consumes it via `var()`, keeping the old 108px/84px values as
pre-hydration fallbacks so SSR paint is unchanged. Runs in a layout
effect so the first client paint already has the measured value.

**Note:** I rejected re-tuning the hardcoded offsets: numbers desyncing
from the header's content-driven height is the root cause, and new
constants re-break on the next copy or breakpoint change.

## Before / after

**Before** (prod: multi-line prices pressed against the row dividers as
one dense block; rows clipped under the sticky category header):
<img width="1442" height="450" alt="pr-before"
src="https://github.com/user-attachments/assets/91d428df-e04c-4494-b454-84a8a46b3ddd"
/>

**After** (this PR: padded cells, each price its own block, headers pin
flush):
<img width="1497" height="375" alt="pr-after"
src="https://github.com/user-attachments/assets/5aa2c3c7-b41e-42c0-8159-bb294a5d1dea"
/>

## To test

Tested on the Vercel preview (Playwright, measured values in parens):
- [x] At a 1024 to 1280px viewport, open /pricing and find the Pipelines
row: the 3 price lines in the Pro and Team cells read as distinct blocks
(row-gap 8px between entries, tight 16px line boxes within an entry,
20px cell padding; verified on localhost pre-push and on the preview,
light and dark)
- [x] Multi-line cell text no longer touches the row dividers: ~21px
from border to text ink top and bottom (was 0-3px)
- [x] At the same width, scroll the whole comparison table: Database and
Auth section headers pin flush below the plan-price header, with no row
text clipped between them (pinned category top within 0.2px of thead
bottom)
- [x] At ~1800px wide: Pipelines and Point in time recovery (Enterprise)
cells show the same separated lines (PITR Enterprise is a single
wrapping string, renders cleanly)
- [x] Resize across 1280px after load: category headers stay flush under
the plan header (ResizeObserver refires; same 0.2px alignment after
1900px to 1150px resize without reload)
- [x] Below 1024px: the mobile comparison view is unchanged
- [x] Added: cold navigation to /pricing#compare-plans lands with
`--pricing-category-top` already applied (151px at 1150px width) and the
pinned header flush
- [x] Added: no new console errors versus the page's pre-existing
baseline

## Linear
- fixes GROWTH-1137
2026-08-26 15:11:15 +08:00
Danny White b5462ee7bb feat(www + studio): promote Select 2026 in www and Dashboard (#49511)
## What kind of change does this PR introduce?

Feature. Promotes Supabase Select 2026 across www and the Dashboard.

## What is the current behavior?

There is no active Select promotion on www or in the Dashboard.

## What is the new behavior?

- Adds a dismissible Select 2026 banner above the www navigation.
- Adds a low-priority Banner Stack card across hosted Studio project
pages.
- Shares a lightweight pixel lockup and CSS-only motion across both
surfaces, with light, dark, and reduced-motion treatments.
- Opens the application page in a new tab and automatically expires both
placements after October 2 in San Francisco.

## To test

- Open `/database` on the www preview. Confirm the banner is legible in
light and dark mode, the complete message remains visible at a phone
width, and the CTA opens `select.supabase.com` in a new tab.
- Dismiss the www banner, then refresh the page. Confirm it stays
dismissed.
- Open any `/project/{ref}` route in the Dashboard preview. Confirm the
Select card appears in the bottom-right Banner Stack behind
higher-priority notices.
- Dismiss the Dashboard card, navigate to another project page, and
confirm it stays dismissed.


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

* **New Features**
* Added a time-limited Select 2026 promotional banner across the website
and Studio.
* Added responsive themed artwork, animated visuals, campaign messaging,
and an external “Apply to attend” CTA.
  * Banner dismissal preferences are saved and respected across visits.
  * Promotion automatically disappears after the campaign ends.

* **Accessibility**
* Improved announcement dismissal controls with semantic buttons and
accessible labels.
  * Added reduced-motion support for promotional artwork.

* **Bug Fixes**
* Improved product-card loading effects to prevent hydration
inconsistencies.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-25 18:07:38 +01: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
shaziya e616c6d267 Add blog post: Enterprise-managed auth for the Supabase MCP server (#49493)
## 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?

New blog post announcing enterprise-managed auth for the Supabase MCP
server, built with Anthropic and Okta.

## What is the current behavior?

No blog post exists for this launch.

## What is the new behavior?

Adds `/blog/enterprise-managed-auth-for-the-supabase-mcp-server` dated
2026-08-24, authored by Cemal Kılıç and Greg Richardson, with the OG and
thumbnail images.

Supersedes #49492 (closed by a branch rename).

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

## Summary by CodeRabbit

* **Documentation**
* Announced general availability of enterprise-managed authentication
for the Supabase MCP server.
* Added details on Okta-based administration through Claude,
user-specific roles and permissions, and centralized onboarding,
offboarding, and access reviews.
  * Included plan availability requirements and setup guidance.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-24 19:33:07 +00: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 78d6d57faa fix(www): stop rendering the invisible Clear all filters button (#49409)
Closes FE-4250

<img width="661" height="294" alt="Screenshot 2026-08-21 at 10 44 38 AM"
src="https://github.com/user-attachments/assets/db7e09db-845c-43a8-a6ca-5d0c67436355"
/>



## Problem

With no filters active, `/features` still rendered the "Clear all
filters" button and hid it with `opacity-0`. Found with VoiceOver, which
announced "You are currently on a button" on an apparently empty
control.

Measured on a preview with no filters active:

| Property | Value |
| -- | -- |
| `opacity` | `0` |
| `visibility` | `visible` |
| `display` | `block` |
| `tabIndex` | `-1` |
| `aria-hidden`, `inert`, `disabled` | none |
| `pointer-events` | `auto` |
| Layout | 256 x 26px |

Two assumptions were wrong. `opacity: 0` does not remove an element from
the accessibility tree, and `tabIndex="-1"` only removes it from tab
order, not the tree. Screen readers walk the tree. It was also a live
256 x 26 mouse target, so a sighted user could click an invisible
button.

## Solution

Render it conditionally, matching `IntegrationsContent.tsx` which
already does this and was unaffected.

No layout shift. The button is the last child of the sidebar column, so
nothing above it moves when it appears.

## Manual testing

1. Open
[/features](https://zone-www-dot-com-git-www-features-clear-filters-button-supabase.vercel.app/features)
with no filters applied. Confirm no "Clear all filters" button exists
anywhere in the DOM.
2. Tick a tag filter in the left sidebar. The button appears.
3. Click it. Every filter clears, the count returns to 79 features, and
the button disappears again.

For the before state, open [/features on
production](https://supabase.com/features) with no filters, then run
this in the console. It reveals the button that is present but
invisible:

```js
const b = [...document.querySelectorAll('button')].find(x => /Clear all filters/.test(x.textContent))
Object.assign(b.style, { opacity: '1', outline: '3px solid red' })
```


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

## Summary by CodeRabbit

* **Bug Fixes**
* The “Clear all filters” button now appears only when filters are
active.
* Improved keyboard navigation by removing inactive filter controls from
the tab order.

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

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 09:38:38 -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
Victor Farazdagi 3bc52101ee (docs/pipelines): early access destinations (#49304)
## What kind of change does this PR introduce?

Docs update


## Summary

- Add Early Access setup and reference guides for ClickHouse, DuckLake,
and Snowflake.
- Update Pipelines navigation and shared documentation with
destination-specific data models, source requirements, schema-change
support, and recovery behavior.
- Keep all three destinations organization-gated. DuckLake is documented
only as a Pipelines replication destination i.e. query compute remains
external and this is not a Warehouse launch.

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

* **New Features**
* Added ClickHouse, DuckLake, and Snowflake as Early Access Pipelines
destinations.
  * Added BigQuery as a managed destination.
* Added destination navigation and setup guides covering configuration,
replication behavior, schema changes, type mappings, troubleshooting,
and monitoring.

* **Documentation**
* Clarified destination availability, regional guidance, requirements,
limitations, and processing behavior.
* Documented destination-specific schema-change support, table identity
requirements, reset behavior, and CDC replication modes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-24 14:44:54 +03: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
Miranda LimonczenkoandClaude Opus 5 21fccb0ecd fix(www): name the /features page button controls (#49343)
Closes FE-4097


https://github.com/user-attachments/assets/bc7cad1a-763e-469f-8a3b-e4d23bed94d9

_See bottom left of screen for screen reader captions._

## Problem

Two controls in the shared `/features/[slug]` template have no
accessible name. Both live in the template, so both fire on all 79
feature pages.

* The feature list dropdown trigger contains only a `List` icon.
`button-name`, critical.
* The breadcrumb back chevron wraps only a `ChevronLeft`. `link-name`,
serious.

## Solution

* Name both with `sr-only` text, matching the sibling prev and next
controls in the same component and the theme switcher in the site
header.
* Label the product pill with its destination. It announced only
"vector", with no indication it filters the catalog. Not an axe finding,
since the product name already supplies a name. The label keeps the
visible word so it satisfies WCAG 2.5.3 Label in Name.
* Fix a stray `className="` inside the `iconClassName` string literal,
which dropped the icons' width class.
* Add `cursor-pointer` to `buttonClassName`. Tailwind 4 no longer sets a
pointer cursor on buttons, so the middle control behaved differently
from its two anchor siblings. This line belongs to FE-4227 and sits here
only to keep two open PRs off adjacent lines of the same file.

## Manual testing

1. Open
[/features/ai-integrations](https://zone-www-dot-com-git-www-features-chrome-access-1aef01-supabase.vercel.app/features/ai-integrations)
using a Screenreader.
2. Tab through the three round controls at top right. They announce
"Previous feature", "Browse all features", "Next feature". **Note:** The
order of the elements is strange; captured in a separate ticket.
3. Tab to the round back control at top left. It announces "Back to all
features".
4. Tab to the product pill beside it. It announces "All vector
features", and the visible word "vector" is unchanged.
5. Hover each of the three round controls. All show a pointer cursor.
6. Run axe on the page. `button-name` and `link-name` report zero
elements.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 08:48:04 -07:00
Pamela Chia f208743432 fix(www): changelog md negotiation slug-set gate (#49357)
Bare-URL `Accept: text/markdown` negotiation never fires on changelog
entries authored after the GitHub-discussions backfill: the middleware
gate `/^changelog\/\d+/` only matches legacy numeric slugs (from
`legacy_gh_discussion` frontmatter), so agents that signal markdown via
Accept get HTML on every new entry. I found this in the independent
review round on #48475; pre-existing, not introduced there.

**Changed:**
- **Non-legacy entries negotiate markdown**: `generateMdContent.mjs` now
lists `public/changelog/*.md` (written moments earlier by
`generateStaticContent.mjs` in the same `content:build:core` chain) and
emits a `CHANGELOG_PAGES` set into the generated module; the middleware
regex becomes a set lookup, so negotiation coverage derives from the
exact static files served and can't drift from what's published.
- **Unknown and deep changelog paths stop negotiating**: the old regex
prefix-matched paths like `changelog/100/bar` and nonexistent numeric
slugs, rewriting them to missing `.md` files (404 under a markdown
Accept); they now pass through to the dynamic route's canonicalizing
308/404.
- **Build guard**: zero collected changelog slugs on Vercel fails the
build (today a zero-entry changelog fetch ships empty output with a
green build), and a shape assertion fails the build if collected slugs
ever lose the `changelog/` prefix the middleware matches on. Locally
without `CHANGELOG_SYNC_APP_*` secrets it warns and changelog
negotiation is off, matching the absent content.
- **`/changelog` index gated the same way**: the index slug is emitted
into the set only when `public/changelog.md` was generated, replacing
the hardcoded `slug === 'changelog'` branch; locally without secrets the
index no longer rewrites to a nonexistent file.

**Note:** script order in `content:build:core` is load-bearing (static
content generation must precede md content generation); the Vercel guard
turns a reorder into a loud build failure instead of a silent empty
gate.

## To test
Tested on the Vercel preview (`zone-www-dot-com` deployment of head
`f451da3`):
- [x] `curl -sI -H "Accept: text/markdown" <preview>/changelog` and
`curl -sI <preview>/changelog.md`: got 200 `text/markdown` (index via
the generated gate)
- [x] `curl -sI -H "Accept: text/markdown"
<preview>/changelog/pipelines`: got 200 `text/markdown` (prod today
returns `text/html`)
- [x] Same curl against the legacy numeric slug
`48235-migration-of-...`: got 200 `text/markdown` (no regression)
- [x] `curl -sI -H "Accept: application/json"
<preview>/changelog/pipelines`: got 406 (prod today returns 200 HTML)
- [x] Explicit `.md` fetches for both slug shapes
(`/changelog/pipelines.md`, `/changelog/48235-....md`): got 200
`text/markdown`
- [x] `curl -sI -H "Accept: text/markdown"
<preview>/changelog/does-not-exist-xyz`: got a 404 HTML passthrough from
the dynamic route, not a 406
- [x] `pnpm test middleware.test.ts` in `apps/www` at head: 41/41 pass
(36 pre-existing + 5 new). No CI job runs the www vitest suite, so this
local run is the only oracle for the new tests.

## Linear
- fixes GROWTH-1062


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

- **New Features**
- Improved changelog page handling, including markdown versions of
published entries.
- Added content negotiation for supported changelog formats, with clear
responses for unsupported requests.
- **Bug Fixes**
- Prevented unpublished numeric-prefix pages from being treated as
published.
  - Fixed deep links under published changelog entries.
- **Reliability**
- Changelog availability is now detected automatically, with improved
validation during content generation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-21 15:01:50 +08:00
Pamela Chia 10c425ad0b feat(www): markdown copy/ask affordances (#48475) 2026-08-21 08:51:11 +08:00
Miranda LimonczenkoandClaude Opus 5 70715790b8 chore(www): unpublish and redirect the legacy launch week pages (#49335)
Closes
[FE-4226](https://linear.app/supabase/issue/FE-4226/unpublish-and-redirect-legacy-launch-week-pages)

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

Content removal.

## What is the current behavior?

`/launch-week/x`, `/launch-week/12`, `/launch-week/13`, and
`/launch-week/14` are still published. Each one carries its own page
component and a ticket flow for a launch week that ended. The
accessibility scan flags them, and they hold no SEO value.

This follows #49281, which took down `/launch-week/6` on the same
pattern.

## What is the new behavior?

- Delete the `/launch-week/x`, `/12`, `/13`, and `/14` page routes.
- Redirect each path to its recap blog post, matching the destinations
agreed in `#team-marketing`.
- Point the Launch Week 12, 13, and 14 blog summary components at
`/launch-week` instead of their deleted pages. `LWXSummary` already does
this.
- Drop the `disableStickyNav` and `showLaunchWeekNavMode` checks in
`Nav` that only matched the deleted routes.
- Drop the Launch Week X branches in `useDarkLaunchWeeks` and `_app`.

| Source | Destination |
| --- | --- |
| `/launch-week/x` | `/blog/launch-week-x-best-launches` |
| `/launch-week/12` | `/blog/launch-week-12-top-10` |
| `/launch-week/13` | `/blog/launch-week-13-top-10` |
| `/launch-week/14` | `/blog/launch-week-14-top-10` |

## Additional context

`/launch-week/7` and `/launch-week/8` stay published. Neither has a
recap post to redirect to, so they need a destination decision before
they come down.

The `components/LaunchWeek/{X,12,13,14}` trees stay. `BlogPostRenderer`
imports the summary component from each one, and those summaries read
the same `Releases/data` modules the deleted pages used. The stage and
nav components under those directories are now unreachable, so they need
their own dead-code audit.

Assets under `public/images/launchweek/` are untouched, same as #49281.

## Manual testing

Preview:
https://zone-www-dot-com-git-www-redirect-legacy-launch-weeks-supabase.vercel.app

1. Open
[/launch-week/x](https://zone-www-dot-com-git-www-redirect-legacy-launch-weeks-supabase.vercel.app/launch-week/x).
It returns a 308 and lands on `/blog/launch-week-x-best-launches`.
2. Open
[/launch-week/12](https://zone-www-dot-com-git-www-redirect-legacy-launch-weeks-supabase.vercel.app/launch-week/12).
It returns a 308 and lands on `/blog/launch-week-12-top-10`.
3. Open
[/launch-week/13](https://zone-www-dot-com-git-www-redirect-legacy-launch-weeks-supabase.vercel.app/launch-week/13).
It returns a 308 and lands on `/blog/launch-week-13-top-10`.
4. Open
[/launch-week/14](https://zone-www-dot-com-git-www-redirect-legacy-launch-weeks-supabase.vercel.app/launch-week/14).
It returns a 308 and lands on `/blog/launch-week-14-top-10`.
5. On each of those blog posts, the launch week summary card header
links to `/launch-week`.
6. Open
[/launch-week](https://zone-www-dot-com-git-www-redirect-legacy-launch-weeks-supabase.vercel.app/launch-week),
[/launch-week/7](https://zone-www-dot-com-git-www-redirect-legacy-launch-weeks-supabase.vercel.app/launch-week/7),
and
[/launch-week/8](https://zone-www-dot-com-git-www-redirect-legacy-launch-weeks-supabase.vercel.app/launch-week/8).
All still load.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 15:33:09 -07:00
Miranda LimonczenkoandClaude Opus 5 ebd399ff87 fix(www): use li instead of ol in launch week summary lists (#49279)
Closes
[FE-4096](https://linear.app/supabase/issue/FE-4096/launch-week-summary-lists-ol-inside-ul-link-where-li-belongs-6-copies)

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

Accessibility bug fix.

## What is the current behavior?

The launch week summary card renders at the bottom of launch week blog
posts. Its two lists are invalid HTML in six copies of the component.

- Each entry is an `<ol>` nested directly inside a `<ul>`. Only `<li>`
is a valid child of `<ul>`.
- The `<Link>` sits inside the `<ol>` rather than inside an `<li>`, so
there are no list items at all.

Screen readers announce a list of empty items wrapping nested lists
instead of a flat list of links.

## What is the new behavior?

- Swap every `<ol>` for an `<li>` in the six summary components: LW X,
11, 12, 13, 14, and 15.
- Class names and keys carry over unchanged. No visual change.

## Additional context

The blog posts stay published. This is a markup fix only.

## Manual testing

1. Open [the Launch Week 15 top 10
post](https://zone-www-dot-com-git-www-fix-lw-summary-lists-supabase.vercel.app/blog/launch-week-15-top-10)
on the deploy preview.
2. Scroll to the Launch Week 15 summary card below the article. It shows
a Main Stage list and a Build Stage list.
3. Inspect either list. Every direct child of the `<ul>` is an `<li>`,
and no `<ol>` appears inside.
4. Repeat on [the Launch Week 12 Wasm FDW
post](https://zone-www-dot-com-git-www-fix-lw-summary-lists-supabase.vercel.app/blog/postgres-foreign-data-wrappers-with-wasm)
for the Launch Week 12 card.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 11:43:51 -07:00
Miranda LimonczenkoandClaude Opus 5 6edef9f067 chore(www): unpublish the Launch Week 6 page (#49281)
Closes
[FE-4100](https://linear.app/supabase/issue/FE-4100/www-remove-httpssupabasecomlaunch-week6)

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

Content removal.

## What is the current behavior?

`/launch-week/6` is still published. Launch Week 6 ran in December 2022.
The page carries its own 1,085-line component, two CSS modules, and a
Supabase client that reads the `lw6_creators` and `lw6_tickets` tables.

## What is the new behavior?

- Delete the `/launch-week/6` page, its CSS modules, its day data, and
its types.
- Redirect `/launch-week/6` to `/blog/launch-week-6-wrap-up`, which
holds the same content.
- Drop the Launch Week 6 card from the archive section on
`/launch-week/8`, leaving Launch Week 7.

## Additional context

Scope is Launch Week 6 only. Whether the other launch week pages come
down is still open with marketing.

Assets under `public/images/launchweek/` are untouched. Several are
shared across launch weeks, so they need their own audit.

## Manual testing

1. Open
[https://zone-www-dot-com-git-www-remove-launchweek-supabase.vercel.app/launch-week/6](https://zone-www-dot-com-git-www-remove-launchweek-supabase.vercel.app/launch-week/6)
on the deploy preview. It returns a 308 and lands on
`/blog/launch-week-6-wrap-up`.
2. Open [the Launch Week 7
page](https://zone-www-dot-com-git-www-remove-launchweek-supabase.vercel.app/launch-week/7).
It still loads.
3. Open [the Launch Week 8
page](https://zone-www-dot-com-git-www-remove-launchweek-supabase.vercel.app/launch-week/8)
and scroll to "Previous Launch Weeks". Only the Launch Week 7 card
shows.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 11:42:30 -07:00
Pamela Chia 9ae6e54dd5 fix(www): exclude redirected slugs from generated markdown (#48476)
11 of the generated `MD_PAGES` entries are blog slugs whose HTML pages
308-redirect away via `apps/www/lib/redirects.js` before any `<head>`
renders. They can never carry an alternate tag and Accept negotiation
never fires (Next.js `redirects()` runs before middleware), so their
`.md` siblings are orphaned content reachable only by guessing the
suffixed URL. Six of them duplicate live, correctly-tagged pages
(`/customers/*`, `/pricing`).

**Changed:**
- `generateMdContent.mjs` derives an exclusion set from
`lib/redirects.js` at generation time: any unconditional exact-match
redirect source (wildcard/param patterns and conditional `has`/`missing`
redirects are skipped) drops the matching slug from both `MD_CONTENT`
and `MD_PAGES`. The build log names every excluded slug, currently the
11 known ones.
- Self-maintaining by design (per the decision recorded on the issue): a
future redirected post auto-excludes on the next build, and removing a
redirect brings its `.md` sibling back. The MDX sources stay in the
repo; nothing is deleted.
- Effect on the 11 slugs: alternate tags stay absent (nothing rendered
them anyway), and explicit `.md` URLs go from serving orphaned markdown
to 404, the same external effect deletion would have had.

## To test

Tested locally:
- [x] `node scripts/generateMdContent.mjs` logs `🚫 Excluded 11
redirected slugs: ...` naming exactly the 11 known slugs; output drops
483 → 472 pages
- [x] Generated file carries no MD_CONTENT/MD_PAGES key for any excluded
slug (raw URL mentions inside other posts' bodies remain, as expected)
- [x] `apps/www` vitest: 71/71 (GROWTH-1013 drift tests unaffected)

Post-merge:
- [ ] `https://supabase.com/blog/case-study-xendit.md` returns 404
(previously 200 orphaned markdown); `https://supabase.com/pricing.md`
still 200

## Linear
- fixes GROWTH-1022


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

## Summary by CodeRabbit

* **Bug Fixes**
* Excluded content with valid exact-path redirects from generated
documentation.
  * Preserved content associated with conditional or wildcard redirects.
* Updated generated page counts and output statistics to reflect the
filtered content.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-20 15:23:13 +08:00
claude[bot]andClaude 8a33c094b4 chore(www): add /evals to the sitemap (#49226)
<!-- ccr-slack-attribution -->
_Requested by **Sean Oliver** · [Slack
thread](https://supabase.slack.com/archives/C07P3AU3J2D/p1787036390117589?thread_ts=1787036390.117589&cid=C07P3AU3J2D)_

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

Chore. One entry added to the www sitemap generator.

## What is the current behavior?

`https://supabase.com/evals` is missing from `sitemap_www.xml`, so
search crawlers are never told the page exists. `robots.txt` doesn't
block it, they just have no way to find it from the sitemap.

The reason is that `/evals` is served by a separate Vercel project and
only reaches supabase.com through a proxy rewrite in
`apps/www/lib/rewrites.js`:

```js
{
  source: '/evals',
  destination: 'https://supabase-evals.vercel.app',
},
```

`apps/www/internals/generate-sitemap.mjs` builds its URL list by
globbing local route source files (`pages/**`, `_blog/*.mdx`,
prerendered `.next/server/pages/**`, etc.) and never resolves rewrites.
There is no page file behind `/evals`, so the globs can't discover it.

Closes GROWTH-1113.

## What is the new behavior?

`https://supabase.com/evals` appears once in the generated
`sitemap_www.xml`, with the same `<changefreq>weekly</changefreq>` and
`<priority>0.5</priority>` as every other entry in the file (no entry in
this sitemap carries a `<lastmod>`).

The entry is a small named const spread into the final `urlset` join,
next to `changelogDetailUrls` — the existing precedent in this file for
URLs with no page file behind them. Nothing else in the script changed,
and the sitemap index output (`sitemap.xml`) is byte-identical.

```diff
+  // /evals is a separate app proxied onto supabase.com via a rewrite in lib/rewrites.js,
+  // so it has no page file for the globs above to find. Hardcode it here.
+  const proxiedAppUrls = [
+    `
+        <url>
+            <loc>https://supabase.com/evals</loc>
+            <changefreq>weekly</changefreq>
+            <priority>0.5</priority>
+        </url>
+      `,
+  ]
+
   const sitemap = `
     <?xml version="1.0" encoding="UTF-8"?>
     <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-        ${[...staticUrls, ...changelogDetailUrls].join('')}
+        ${[...staticUrls, ...changelogDetailUrls, ...proxiedAppUrls].join('')}
     </urlset>
     `
```

This only makes the URL discoverable. Whether the page content itself is
crawlable is separate work, tracked in the evals repo.

## Additional context

Verification, run locally against this branch. The generator runs
standalone (`node ./internals/generate-sitemap.mjs` from `apps/www`); a
missing `.next` just means the globs match fewer pages, and the missing
changelog RSS is caught internally.

I generated `sitemap_www.xml` from `master` and from this branch and
diffed the two. The added entry is the only difference:

```
3271a3272,3277
>
>   <url>
>     <loc>https://supabase.com/evals</loc>
>     <changefreq>weekly</changefreq>
>     <priority>0.5</priority>
>   </url>
```

Exactly one occurrence, with its neighbouring entry for context:

```
$ grep -c '<loc>https://supabase.com/evals</loc>' public/sitemap_www.xml
1

  <url>
    <loc>https://supabase.com/terms</loc>
    <changefreq>weekly</changefreq>
    <priority>0.5</priority>
  </url>

  <url>
    <loc>https://supabase.com/evals</loc>
    <changefreq>weekly</changefreq>
    <priority>0.5</priority>
  </url>
</urlset>
```

Other checks:

- Both outputs parse as well-formed XML (Python `xml.dom.minidom`):
`sitemap_www.xml` has 545 `<url>` elements, `sitemap.xml` parses OK.
- `sitemap.xml` (the sitemap index) is identical to the pre-change
output; `diff` reports no changes.
- `npx prettier --check internals/generate-sitemap.mjs` → "All matched
files use Prettier code style!"
- Both generated sitemaps are gitignored (`apps/www/.gitignore` lines
29-30), confirmed with `git check-ignore`. `git status` shows only
`apps/www/internals/generate-sitemap.mjs`, so no generated file is in
the commit.
- No test, snapshot, or fixture anywhere in the repo references the
sitemap generator, so there was nothing to run. Its only caller is
`apps/www`'s `postbuild` script.

Not run: `pnpm --filter=www build`. It fails during "Collecting page
data" on a clean `master` checkout in this environment too, so the
failure is pre-existing and unrelated, and this change needs no build to
verify.

Co-authored-by: Claude <noreply@anthropic.com>
2026-08-19 23:15:29 +01:00
Ana cb9394246b blog(www): connect client traces to your logs (#49200)
## 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?

- New blog post

## What is the current behavior?

N/A, new content for the Logs with Traces launch (August 18, 2026).

## What is the new behavior?

- Adds
`apps/www/_blog/2026-08-18-connect-client-traces-to-your-logs.mdx`,
announcing W3C Trace Context propagation in supabase-js
- Covers setup, the Log Drains correlation angle, current limitations,
and an upgrade note for anyone on `tracePropagation` from a version
before 2.112.0
- Notes that Swift, Flutter, and Python are also covered, linking to the
docs for per-language setup rather than hardcoding a list that will need
updating as more languages ship
- Adds social and thumbnail images at
`apps/www/public/images/blog/connect-client-traces-to-your-logs/`

## Additional context

N/A

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

## Summary by CodeRabbit

## Documentation

* Added a blog post covering W3C Trace Context propagation from client
applications to API Gateway and Edge Function logs.
* Documented OpenTelemetry setup, trace propagation configuration,
active spans, sampling overrides, and Log Drains integration.
* Clarified supported environments and domains, current limitations,
version requirements, and links to setup guidance.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-18 12:53:22 -04:00
AnaandSteven Eubank 0a677ac9ee feat(www): add client-side trace propagation to Logs & Analytics (#49161)
## 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 page content update (`apps/www/data/features.tsx`)
- Docs link fix

## What is the current behavior?

The Logs & Analytics feature page entry covers Supabase exporting its
own telemetry outward (OpenTelemetry export, Metrics API) but does not
mention client-side trace propagation. The Log Drains entry links a
stale docs URL.

## What is the new behavior?

- Logs & Analytics entry now also covers client-side trace propagation:
supabase-js, Swift, Flutter, and Python can propagate W3C Trace Context
to Supabase so a client trace and the corresponding Supabase logs share
a `trace_id`, added as a new paragraph and Key benefit
- Log Drains entry's `docsUrl` fixed from `/guides/telemetry/log-drains`
to `/guides/monitoring-and-debugging/log-drains`

## Additional context

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

## Summary by CodeRabbit

* **New Features**
* Added information about W3C trace-context propagation for Logs &
Analytics.
* Documented supported client libraries, tracer integrations, opt-in
behavior, and shared `trace_id` correlation.

* **Documentation**
  * Updated the Log Drains documentation link.

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

---------

Co-authored-by: Steven Eubank <47563310+smeubank@users.noreply.github.com>
2026-08-18 11:47:11 -04:00
Danny White 14fe0c0cc8 fix(studio): slightly round split-button corners on focus (#49129)
## What kind of change does this PR introduce?

UI polish for split buttons (primary action + dropdown chevron).
Follow-up to #49055.

## What is the current behavior?

The focus ring sits above the neighbouring half, but the inner edge
stays square, so the ring has two sharp corners at the join.

## What is the new behavior?

On keyboard focus, the squared-off edge uses a slight radius so the ring
matches the outer corners more closely. Resting state is unchanged.
Split-button callsites now share the same join classes as the
design-system example.

| Before | After |
| --- | --- |
| <img width="1030" height="296" alt="43471"
src="https://github.com/user-attachments/assets/9df3bd72-c7ac-4419-ae18-a7e649dc2d66"
/> | <img width="1056" height="276" alt="CleanShot 2026-08-17 at 10 45
09@2x"
src="https://github.com/user-attachments/assets/52e8a4dc-9c52-45ce-b4d0-f0e7b1b75935"
/> |

## To test

Tab to each half (labelled button, then chevron). Inner corners of the
focus ring should be slightly rounded, not square.

1. [Split with
dropdown](https://design-system-git-fix-split-button-focus-radius-supabase.vercel.app/design-system/docs/components/button#split-with-dropdown)
(no login)
2. [Access
Tokens](https://studio-staging-git-fix-split-button-focus-radius-supabase.vercel.app/dashboard/account/tokens)
→ Generate new token
3. Any project on [studio
staging](https://studio-staging-git-fix-split-button-focus-radius-supabase.vercel.app/dashboard/_/settings/general)
→ Settings → General → Restart project

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

## Summary by CodeRabbit

- **Accessibility**
  - Added accessible labels to dropdown and export controls.
- Improved keyboard-focus visibility, layering, and rounded edge
treatment across joined buttons and menus.
  - Removed misleading or redundant screen-reader text and titles.

- **Bug Fixes**
- Prevented split-button controls from shrinking or displaying awkward
borders and corners.
- Refined hover and focus behavior for action buttons throughout
settings, database, storage, account, and documentation interfaces.

- **Documentation**
- Clarified guidance for using overflow menus and responsive
split-button actions.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-17 17:28:22 +10:00
Prashant Sridharan 344dc26a5e Fixed the event classifier for the events page (#49095)
## 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?

Modified the events page so that it reads the correct category from the
Notion database and displays if it's a hackathon, meetup, etc.

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

## Summary by CodeRabbit

* **New Features**
* Events now display categories based on their Notion type and category
information.
  * Hackathon events can be identified through category data.
  * Duplicate categories are automatically removed.

* **Bug Fixes**
* Events with unrecognized types now default to the conference category
for consistent display.


<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-14 17:43:17 +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
claude[bot] 00952806f2 fix(www): correct three outdated pricing page FAQ answers (#49036) 2026-08-13 04:58:07 +00:00
Miranda Limonczenko de39dda387 docs: replace Pico references with Nano in Supabase for Platforms content (#48958) 2026-08-12 11:55:17 -06: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
Wendie CheungandWendie Cheung beee91b9c2 fix(www): restore monochrome customer logos for QA.tech and Lovable (#48964)
## What kind of change does this PR introduce?

Bug fix for the two visual bugs flagged in
[#customers-page-feedback](https://supabase.slack.com/archives/C072FL5KKKP/p1786496881213419):

- QA.tech was missing its light-mode logo
- Lovable's logo was coloured, inconsistent with the monochrome
convention used by every other customer logo

## What is the current behavior?

- `on-light/qa-tech.png` is a white wordmark, so it's invisible against
the light-mode background.
- `on-light/lovable.png` and `on-dark/lovable.png` both use Lovable's
gradient heart mark instead of a monochrome one.

## What is the new behavior?

- `on-light/qa-tech.png` recolored to a black wordmark, transparent
background — visible in light mode, matches the existing white
`on-dark/qa-tech.png` used in dark mode.
- `on-light/lovable.png` recolored to solid black, `on-dark/lovable.png`
recolored to solid white — both transparent background, no brand colour,
consistent with the other customer logos.

No code changes; only the three PNG assets.

Co-authored-by: Wendie Cheung <wendie.cheung@supabase.io>
2026-08-12 14:42:27 +10: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
Miranda LimonczenkoandClaude Opus 5 6d3a4bcc48 feat(www) Add scaffolding for WWW E2E tests and CI check (#48861)
Closes DOCS-1278

## 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. Adds E2E test scaffolding and a CI check for the marketing
site.

## What is the current behavior?

Closes [FE-4047](https://linear.app/supabase/issue/FE-4047).

The marketing site has no E2E coverage. Docs has a suite in `e2e/docs`,
but its
runner, git helpers and axe reporting are private to that package, so a
second
site cannot reuse them.

## What is the new behavior?

* **A www suite scoped to changed content.** Changed `.mdx` files in
`_blog`,
`_events`, `_customers` and `_alternatives` map to the URLs they render.
Pages
with `disable_page_build: true` are skipped because they 404 by design.
Capped
at 20 pages. Enforces `heading-order` and `page-has-heading-one`,
matching docs.
* **`e2e/shared` The docs site is also static with similar needs. This
folder shares the docs logic with www.
* **A CI check that is safe to mark required.** Path scoping lives in a
`Detect changed paths` step rather than a `paths:` trigger, so the check
  reports on every pull request instead of being skipped.
`waitForVercelDocsPreview.js` becomes `waitForVercelPreview.js`, shared
by both
  workflows.

## How the check behaves

The job always reports a check run, so it is safe to mark required. Path
scoping
happens in a step rather than a `paths:` trigger, which would leave
non-www pull
requests waiting on a check that never reports.

| Case | Behavior |
| --- | --- |
| Fork pull request adds new pages | Passes without testing. The Vercel
wait is gated on `head.repo.full_name == github.repository`, so forks
resolve no preview URL. The job emits a `::warning` and a job summary
containing a ready-to-run `gh workflow run www-e2e.yml` command with the
resolved page paths, so a maintainer can run it against the preview. |
| Vercel preview times out or fails | Passes without testing. The wait
step is `continue-on-error: true`, so a 900s timeout or a failed
deployment leaves the URL unset and the suite skips. Vercel's own
`Vercel – zone-www-dot-com` check already reports the failure. |
| Draft pull request | Job does not run at all, gated at the job level
on `pull_request.draft == false`. `ready_for_review` is in the trigger's
`types`, so marking it ready runs the check. |
| Another app changed, www untouched | Job runs and every step skips.
The `www` filter matches only the four content directories, `e2e/www`,
`e2e/shared`, the lockfile, and this workflow. |
| Only the harness changed | Passes without testing. Scope resolves to
zero pages, and the Vercel wait is additionally gated on `www_app`, so
it does not wait for a preview Vercel skipped. |
| No preview resolves, any reason | Skips rather than falling back to
production. Production does not serve pages the pull request adds, so
testing it would fail a valid change. |

### Not covered

Changes to `apps/www` components and routes do not trigger this check —
only the
four content directories do. A follow-up can check global components
such as the navigation and the footer.

## Manual testing

1. Start the site: `pnpm dev:www`
2. Run `pnpm e2e:www` with no www content changed. It should resolve
zero pages
   and skip Playwright, not fail.
3. Touch a post, then run `pnpm e2e:www` again:
`echo "" >> apps/www/_blog/2024-01-01-some-post.mdx`. The resolved
`/blog/...`
   path should be listed before Playwright starts.
4. Run against production with no local server:
`PLAYWRIGHT_BASE_URL=https://supabase.com
WWW_E2E_PAGE_PATHS=/blog/postgres-language-server pnpm e2e:www`
5. Point step 4 at a page with a known heading problem. The failure
should name
   the rule, the CSS selector and the markup.
6. Confirm docs still passes on the shared runner: `pnpm dev:docs`, then
   `pnpm e2e:docs`

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

* **New Features**
* Added WWW end-to-end testing for affected content pages, including
accessibility checks.
* Added standard and full-site test commands, configurable preview
testing, and failure reports.
* Added shared utilities for page discovery, accessibility scanning, and
test execution.

* **Documentation**
* Documented WWW test setup, coverage, debugging, CI behavior, and
running checks against production or preview environments.

* **Improvements**
* Updated documentation test workflows to better identify affected
changes and handle preview environments.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 22:06:51 +00:00
David_CandPamela Chia 6bda113bf0 fix(www): fix duplicate row level security key (#48325)
## 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 (fixes #48324)

## What is the current behavior?

Detailed in #48324, there's a duplicate row-level-security section. Line
369 to 392 (right above the change) already have this row-level-security
section, seems like a simple forget to change the copy pasted content
mistake

## What is the new behavior?

Fixed based on the title and image name



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

* **Content Updates**
* Replaced the “Row Level Security” feature card with “Full SQL access”
in the Postgres platform features section.
  * Updated the associated image description to “SQL Editor.”
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Pamela Chia <pamelachiamayyee@gmail.com>
2026-08-12 02:25:37 +08:00
Ayaan GazaliandPamela Chia 0cf543add9 docs(blog): point dead docs links at their current pages (#48683)
## 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?

Docs fix (broken links in blog posts).

## What is the current behavior?

Three links in two published blog posts 404:

| link | post |
| --- | --- |
| `/docs/guides/platform/log-drain#generic-http-endpoints` |
`2024-08-15-log-drains.mdx` |
| `/docs/reference/javascript/storage-from-download` |
`2022-12-13-storage-image-resizing-smart-cdn.mdx` |
| `/docs/reference/dart/storage-from-list` | same post |

The log drains guide is at `log-drains` (plural) now, and the JavaScript
and Dart Storage references were reorganized under `file-buckets-*` ids.

## What is the new behavior?

- `guides/platform/log-drain#generic-http-endpoints` becomes
`guides/platform/log-drains#custom-endpoint`
- `reference/javascript/storage-from-download` becomes
`reference/javascript/file-buckets-download`
- `reference/dart/storage-from-list` becomes
`reference/dart/file-buckets-list`

All three destinations return 200.

On the log drains one, the old `#generic-http-endpoints` heading is gone
too, so I checked what replaced it rather than just fixing the path and
leaving a dead fragment. The `#custom-endpoint` section on that page is
the same thing the blog paragraph is describing: "Logs are delivered as
a JSON array via HTTP POST", with a URL, HTTP version, gzip and headers
configuration. That matches "the HTTP Endpoint drain can be used to send
logs to any destination that supports ingestion via HTTP POST requests"
in the post, so I pointed it there. Happy to change it if you would
rather it went to the page top or somewhere else.

## Additional context

Files:

- `apps/www/_blog/2024-08-15-log-drains.mdx` (1)
- `apps/www/_blog/2022-12-13-storage-image-resizing-smart-cdn.mdx` (2)

Verification: all three old URLs confirmed 404, all three replacements
confirmed 200. For the fragment I fetched the log drains page and
confirmed `#generic-http-endpoints` is not among its heading ids while
`#custom-endpoint` is, then read that section's text to check it is the
right one.

I did not touch `apps/www/app/api-v2/md/content.generated.ts`, which
mirrors blog content, since it is generated and will pick this up on its
next build.

Gates run locally: `test:prettier` passes repo wide and the www vitest
suite passes (6 files, 73 tests). I did not run `pnpm build`, which
cannot complete in my environment because the docs
`build:federated-content` step needs `DOCS_GITHUB_APP_PRIVATE_KEY`.

This came out of checking every absolute `supabase.com/docs` link in
`apps/www` and `apps/docs/content` against the live site. Two related
things I found in the same sweep but deliberately left alone, because
the target is a content decision rather than a rename: a few links into
`elevenlabs/examples` whose examples were removed when that repo
restructured by language, and `redwoodjs/redwoodjs-supabase-quickstart`,
whose repo no longer exists.

Freshman contributor, worked through this with Claude Code's help and
checked each URL and heading id myself.


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

* **Documentation**
* Updated JavaScript and Dart getting-started links to their current
client-library pages.
* Corrected the custom HTTP endpoint documentation link for log drains.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Pamela Chia <pamelachiamayyee@gmail.com>
2026-08-12 01:00:46 +08:00
Ayaan GazaliandPamela Chia 279e577fac fix(www): correct broken product carousel and partner logo image paths (#48822)
## 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 (broken images on the database product page and the agencies
solutions page).

## What is the current behavior?

Five image paths point at files that are not in the repo, so they 404 in
production. Four of them are carousel slides on the database product
page, which means those slides render with a broken image.

| referenced | actually committed |
| --- | --- |
| `sql-view/manaco-editor.png` | `sql-view/monaco-editor.png` |
| `table-view/spreadsheet-interface.png` | `table-view/spreadsheet.png`
|
| `table-view/create-table.png` | `table-view/create-tables.png` |
| `table-view/export.png` | `table-view/export-csv.png` |
| `logos/publicity/sj-innovation.svg` |
`logos/publicity/sjinnovation.svg` |

All five confirmed 404 on production, and all five replacements
confirmed 200.

## What is the new behavior?

Each path points at the file that is actually committed. No assets
added, renamed or deleted.

The mapping is not guesswork, each slide's own title and text names the
image:

- the `manaco-editor` slide is titled "Monaco editor" with the text
"Built in Monaco editor, with rich validation and autocomplete", so that
is a plain spelling slip for `monaco-editor.png`
- the `create-table` slide is titled and labelled "Create tables",
plural, matching `create-tables.png`
- the `export` slide is "Select and Export" with the text "Pick the rows
you want and export them into a CSV", matching `export-csv.png`
- the `spreadsheet-interface` slide is "The simplicity of a
spreadsheet", matching `spreadsheet.png`

I also checked the dark and light convention before picking: every other
slide in both carousels uses the plain filename rather than the `-light`
variant, so I stayed consistent with that and did not switch any slide
to a `-light` asset.

## Additional context

Files:

- `apps/www/data/products/database/sql-view-carousel.json` (1)
- `apps/www/data/products/database/table-view-carousel.json` (3)
- `apps/www/data/solutions/agencies.tsx` (1)

How I found it: compared every `/images/...` reference across `apps/www`
(2152 distinct paths) against `apps/www/public`, then for each miss
looked for a near match in the same directory before deciding anything,
and finally live-checked both the broken path and the proposed
replacement.

One in the same file I could not fix:
`apps/www/data/solutions/agencies.tsx` also references
`logos/publicity/imaginary-space.svg`, which 404s and has no similarly
named asset anywhere in that directory. That one needs the actual logo,
so it is not something I can resolve from the repo.

Gates run locally: `test:prettier` passes repo wide, `typecheck` passes
16/16, and the www vitest suite passes (6 files, 73 tests). I did not
run `pnpm build`, which cannot complete in my environment because the
docs `build:federated-content` step needs `DOCS_GITHUB_APP_PRIVATE_KEY`
and fails before Next compiles.

Freshman contributor, found these with a local asset scan and verified
every status code myself, with Claude Code's help along the way.

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

## Summary by CodeRabbit

* **Bug Fixes**
  * Corrected image references in the SQL view and table view carousels.
* Updated illustration paths for spreadsheet editing, table creation,
and CSV export content.
  * Fixed the SJ Innovation testimonial logo so it displays correctly.

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

Co-authored-by: Pamela Chia <pamelachiamayyee@gmail.com>
2026-08-12 00:50:16 +08:00
Ayaan Gazali 0925218294 fix(www): point Infinite Query announcement at its live docs page (#48946)
## 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 (broken link on the Wrapped product announcements page).

## What is the current behavior?

`ProductAnnouncements.tsx` links the "Supabase UI Library now includes
Infinite Query block" entry to
`https://supabase.com/library/docs/infinite-query-hook`, which returns
404.

The docs page for that block is framework scoped, and the slug does not
carry the `-hook` suffix. The content only exists for two frameworks:

| URL | status |
| --- | --- |
| `/library/docs/infinite-query-hook` (current) | 404 |
| `/library/docs/react/infinite-query` | 200 |
| `/library/docs/vue/infinite-query` | 200 |
| `/library/docs/nextjs/infinite-query` | 404 |

Those two match the content tree exactly,
`apps/ui-library/content/docs/{react,vue}/infinite-query.mdx`, and there
is no `nextjs` variant.

## What is the new behavior?

The entry points at `/library/docs/react/infinite-query`, confirmed 200.

I picked React rather than Vue deliberately. That page is the original,
added in #34650 ("Infinite query hook block"), and its front matter is
`title: Infinite Query Hook` with `description: React hook for infinite
lists, fetching data from Supabase`, which is what the announcement is
describing. Vue and Nuxt came later in #44426. The `-hook` in the old
URL matches the registry item name (`<RegistryBlock
itemName="infinite-query-hook" />`), not the docs slug, which is
probably how the two drifted apart.

## Additional context

This one was already stale before the recent rename. #48668 moved `/ui`
to `/library` and rewrote this line mechanically from
`/ui/docs/infinite-query-hook` to `/library/docs/infinite-query-hook`,
so the dead path was carried across rather than introduced. Both
spellings 404 today, so it reproduces on current master either way.

The rename itself looks correct, and I checked rather than assumed:

- every other `/library` URL referenced anywhere in the repo returns
200, including the sibling `nextjs/social-auth` entry immediately below
this one
- the two specific `/ui/docs/ai-editors-rules/*` redirects sit above the
new `/ui/:path*` catch all in `redirects.js`, so first match wins keeps
them working
- `https://supabase.com/library/docs` also 404s, but that is a
`BASE_URL` constant in the two `build-llms-txt.ts` scripts that gets
concatenated with a page path, not a link anyone follows, so I left it
alone

One file, one line.

Verification: every status code above was checked against production,
including a deliberate nonsense URL to confirm the check was actually
running. Gates on this branch: `test:prettier` passes repo wide,
`typecheck --filter=www --force` passes 8/8, the www vitest suite passes
(6 files, 74 tests), and `next.config.test.ts` passes. I did not run
`pnpm build`, which cannot finish in my environment because the docs
`build:federated-content` step needs `DOCS_GITHUB_APP_PRIVATE_KEY`.

Freshman contributor here. Found this with Claude Code's help while
checking the URLs touched by the `/ui` to `/library` rename, and I
verified every status code and the page history myself.


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

## Summary by CodeRabbit

* **Bug Fixes**
* Updated the April 2025 Infinite Query announcement link to point to
the React-specific documentation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-12 00:07:49 +08:00
Katerina Skroumpelouandgithub-actions[bot] fc5db9bb03 docs: update client-side tracing and Edge Function CORS guides (#48924)
Updates the client-side tracing and Edge Function CORS docs for changes
shipping in `@supabase/supabase-js` v2.112.3 (supabase/supabase-js#2603,
supabase/supabase-js#2604). The tracing guide gains a vendor
compatibility table (plain OpenTelemetry works as is, Sentry needs
`propagateTraceparent: true`, Datadog RUM needs `allowedTracingUrls`),
the new `respectSamplingDecision` semantics (non-sampled requests now
carry `traceparent` only, so logs stay correlatable), a troubleshooting
entry for the SDK's new propagator warning, and a note that browser
calls to Edge Functions need the trace headers in the function's CORS
allow-list. The CORS guide now states explicitly that trace headers are
sent only when trace propagation is opted in (never by default), adds a
table of when each SDK header is actually sent, and the hardcoded
`corsHeaders` examples are updated to the full header list. Should merge
after the v2.112.3 release is published, since it documents that
version's behavior.

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

* **Documentation**
* Expanded CORS guidance with trace-propagation requirements and SDK
version considerations.
* Added browser and Edge Function setup guidance for client-side
tracing.
* Documented updated sampling behavior, advanced configuration, vendor
setup examples, and troubleshooting.

* **Bug Fixes**
* Updated CORS configurations to allow retry and tracing headers
required for supported requests.
* Improved compatibility for browser requests that transmit distributed
tracing context.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-11 16:43:26 +03:00
Saxon Fletcher cb35e1f98e chore(library): update routes, redirects, and naming (#48668)
Our UI Library registry is expanding to include blocks that go beyond UI
and in some cases focus purely on back-end. This PR is a precursor to
adding more back-end related blocks. This PR includes the `ui-library ->
library` rename plus redirects and small UI copy updates. Since this is
a rename we'll need to update Vercel configuration.

## Vercel rollout

Keep the Library project Root Directory as `apps/ui-library`

1. In the **Library** Vercel project, set:

   `NEXT_PUBLIC_BASE_PATH=/library`

Apply it to Preview and Production, then redeploy the Library project.

2. In the **www** Vercel project, add:

`NEXT_PUBLIC_LIBRARY_URL=<current value of NEXT_PUBLIC_UI_LIBRARY_URL>`

Apply it to Preview and Production. Keep `NEXT_PUBLIC_UI_LIBRARY_URL`
during the migration, then redeploy the www project.

3. Deploy in this order:

   1. Library project
   2. www project

4. Validate:

   - `/library`
   - `/library/docs/nextjs/password-based-auth`
   - `/ui` redirects to `/library`
- `/ui/docs/nextjs/password-based-auth` redirects to
`/library/docs/nextjs/password-based-auth`
- `/ui/docs/ai-editors-rules/*` still uses its existing Docs redirects

No Vercel dashboard redirect rules are needed. Environment-variable
changes require a new deployment.

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

* **New Features**
* Supabase UI Library has been renamed to **Supabase Library** across
navigation, pages, documentation, and resource links.
* The Library is now available at `/library`, with updated descriptions
covering components, blocks, and developer tools.
* **Bug Fixes**
* Added permanent redirects from legacy `/ui` URLs to corresponding
`/library` paths.
* Updated links throughout the site and documentation to prevent broken
navigation and references.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-11 13:37:32 +10:00
claude[bot]andClaude 86854671e9 feat(www): add Open Authorization Integration Addendum (#48804)
<!-- ccr-slack-attribution -->
_Requested by **Nicole Kramer** · [Slack
thread](https://supabase.slack.com/archives/C0161K73J1J/p1786027145751449)_

## 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 — a new legal page on the marketing site (`apps/www`).

## What is the current behavior?

**Before:** the Program Addenda page at
`/legal/partner-resources/program-addenda` lists exactly one addendum,
the Integration Partner Addendum. There is no published Open
Authorization (OAuth) addendum anywhere on the site.

## What is the new behavior?

**After:** the Program Addenda page also lists the **Open Authorization
Integration Addendum**, linking to a new page at
`/legal/partner-resources/program-addenda/oauth-partner-addendum`.
Formatting, breadcrumbs, version selector, and listing badge all match
the existing Integration Partner Addendum.

**How:** three files.

-
`apps/www/data/legal/partner-resources/oauth-partner-addendum/20260806-v1.mdx`
— the addendum text, formatted to match
`integration-partner-addendum/20260615-v1.1.mdx` (escaped section-number
periods, `####` run-in headings for the lettered subsections, italic
`_Label_` run-in labels for the enumerated data-protection clauses,
explicit `[url](url)` links).
-
`apps/www/pages/legal/partner-resources/program-addenda/oauth-partner-addendum.tsx`
— the page, mirroring `integration-partner-addendum.tsx` with a
single-version `versions` array.
- `apps/www/lib/addenda.ts` — adds a small `TITLE_OVERRIDES` map. The
listing derives titles by capitalizing slug words, which turns
`oauth-partner-addendum` into "Oauth Partner Addendum"; the override
makes the listing link read the same as the page's `h1`.

No other wiring was needed: the addenda listing is generated from the
directory, so there is no hub entry, redirect, rewrite, sitemap entry,
or `noindex` rule to add.

## Additional context

Two things for the requester to confirm:

- **The effective date is an assumption.** The addendum document itself
contains no date. The listing and version label derive the effective
date from the `YYYYMMDD` filename prefix, so this file is dated **August
6, 2026**, taken from the source document's own filename (`2026.08.06 -
Supabase-OAuthAddendum-ONLINE.docx`). To change it, rename the file — no
code change required.
- **The legal text is a verbatim transcription.** Source wording,
capitalization, and punctuation are preserved exactly as drafted,
including anything that reads like a typo. Only markup was added; the
plain text was diffed against the transcription and is
character-identical. Please review the wording itself rather than
assuming it was copy-edited.

One wording choice that was not in the source document: the page
subheader, "An addendum to the Master Partner Program Agreement
governing OAuth integrations." It mirrors the one-line subheader style
of the existing addendum page and is easy to reword.

## Also fixed here: a literal `(c)` rendered as `©` in legal headings

While formatting the new addendum we hit a rendering bug that turned out
to be **already live on supabase.com**, not new to this branch.

The heading font, **Manrope**, ships a default-on standard `liga`
feature that maps the glyph sequence `parenleft c parenright` to the
copyright glyph. So a literal `(c)` anywhere inside an `h2`–`h6` on the
marketing site paints as `©`. Body copy is unaffected because it uses
Inter, whose subset has no such ligature — which is why this only ever
shows up in headings.

This branch adds a `legal-prose` utility (`font-variant-ligatures:
no-common-ligatures`) in `apps/www/styles/globals.css` and applies it to
two pages:

- the new **Open Authorization Integration Addendum** page (heading
`#### (c) Security.`), and
- the **Master Partner Program Agreement** page, where the `#### (b)
Such indemnity …` heading in section 17.1 contains `… ; or (c) replace
the Covered Materials …` about 600 characters into the line. That page
was **already published**, and rendered "or © replace the Covered
Materials" in production.

The MPPA change is one word — `className="prose"` → `className="prose
legal-prose"`. **No legal text was modified**: no HTML entities, no
zero-width characters, no rewording, no re-hyphenation. The DOM still
holds `U+0028 U+0063 U+0029`; only the font's shaping is suppressed.
Verified in Chromium against the real heading text and the same two font
subsets `next/font` serves: the `(c)` run measures **15.36px** before
the fix (a single `©` glyph) and **22.05px** after (three literal
glyphs), against a 23.30px control for the `(b)` in the same heading.

All 17 `.mdx` files under `apps/www/data/legal/` were swept for `(c)`
and the other Manrope `liga` input sequences (`--`, `->`, `<-`, `(>)`,
`<3`) on heading lines. The only two hits are the two pages fixed above;
nothing else needs the utility today. (Headings do contain
`ff`/`fi`/`fl`/`tt` — those ligatures are ordinary typography and are
intentionally left alone.)

**For future legal pages:** because the cause is the heading font's
default ligature rather than anything about these documents, any new
legal page whose source has `(c)` in a heading will need `legal-prose`
on its prose container too.

**One side effect worth flagging:** `no-common-ligatures` is blunt, so
on those two pages it also suppresses the ordinary `fi`, `ff` and `tt`
ligatures — a sweep of the legal `.mdx` files counts 107 such
occurrences in headings (`fi` 83, `ff` 21, `tt` 3, `fl` 0), so the note
above about leaving them alone holds for the rest of the site rather
than for these two pages. That is a deliberate trade-off: correctness of
the legal text beats typographic polish on two addendum pages. A
narrower alternative exists — `font-feature-settings: "liga" 0` scoped
to just the offending ligature, or overriding only the
`parenleft_c_parenright` substitution — but it is more fragile and more
subset-specific, so push back here if you would rather have that
instead.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01VtcJJGqw5jL1ESwhs8DGCu

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-08-07 15:54:37 +02:00
shaziya 2e633a3fbe Add blog post: Supabase is now a connector on Perplexity Computer (#48776) 2026-08-07 03:05:23 -07:00
shaziya a71636f5a0 feat(marketing): add hint text below Go page form labels (#48824)
## 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?

Small feature addition to `packages/marketing` (Go page form
schema/renderer), plus a copy/layout change on
`/go/select-2026/partner-day`. Supersedes #48821 (closed), which is
folded in here.

## What is the current behavior?

Go page form fields only support a `description` string rendered *below
the input*. There's no way to put a short note directly under a field's
label, above the input — so the Partner Day RSVP's "attending" question
crammed "(your Partner Day invite covers it)" into the question text
itself.

## What is the new behavior?

- Adds an optional `hint` string to the Go page form field schema
(`packages/marketing/src/go/schemas.ts`), rendered as small italic text
directly beneath the label, above the input
(`packages/marketing/src/forms/MarketingForm.tsx`).
- Updates the Partner Day RSVP's "attending" field to use it: the
question is now "Would you like to attend Supabase Select on October 2?"
with "Your Partner Day invite covers it" as a separate grey/italic hint
line underneath.
- No other fields set `hint`, so this is backward compatible — verified
`vip-experience`'s identical select field (no `hint` set) renders
unchanged.

## Additional context

- Verified locally in the browser: the new hint renders correctly on
Partner Day, and other `_go` pages with form fields are unaffected.
- `prettier --check` and `tsc --noEmit` both pass on the changed files.

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

## Summary by CodeRabbit

* **New Features**
* Added optional hint text beneath form field labels, displayed in
smaller italic text.
* Updated the Select RSVP question to clearly distinguish the attendance
prompt from invite coverage details.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-07 05:33:47 +00:00
Wendie CheungandWendie Cheung 91a394fc83 Use white wordmark for QA.tech primary logo (#48827)
Follow-up to #48798. The primary `logo` was a black app-icon-badge
(square background), inconsistent with other customer logos (transparent
wordmark/mark, e.g. Brevo). Per explicit direction, this swaps in the
same white-on-transparent wordmark already used for `logo_inverse`.

**Known tradeoff:** the primary `logo` renders on the site's light-mode
background, so this white wordmark will be invisible there. This was
confirmed and explicitly accepted rather than left as an oversight.

Co-authored-by: Wendie Cheung <wendie.cheung@supabase.io>
2026-08-07 12:05:47 +10:00
Wendie Cheung 6ac0316738 Add QA.tech customer case study (#48798) 2026-08-07 08:50:44 +10:00
shaziya e0cc680653 feat(www): update Partner Day at Select 2026 go page copy (#48778)
## 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?

Content update (marketing copy) for the `www` app.

## What is the current behavior?

`/go/select-2026/partner-day` copy is a couple of revisions behind the
latest Notion draft (see #48771 and #48773 for prior rounds).

## What is the new behavior?

Updates the page copy to match the newest draft.

## Additional context

- Verified locally in the browser against the Notion copy doc,
word-for-word.
- `prettier --check` passes on the changed file.

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

## Summary by CodeRabbit

* **Content Updates**
* Clarified Partner Day event details, including the day-before-Select
note.
  * Improved venue information messaging.
* Updated the RSVP question to reference Select on October 2 and the
Partner Day invitation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-06 01:08:56 +00:00
shaziya 8d1ff7d38f feat(www): update Partner Day at Select 2026 go page copy (#48773)
## 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?

Content update (marketing copy) for the `www` app.

## What is the current behavior?

`/go/select-2026/partner-day` copy is one revision behind the latest
draft (see #48771 for the prior round).

## What is the new behavior?

Updates the page copy to match the newest Notion draft.

## Additional context

- Verified locally in the browser against the Notion copy doc,
word-for-word.
- Verified the RSVP form's "Are you attending Select 2026?" select field
opens, selects, and submits correctly.
- `prettier --check` passes on the changed file.

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

## Summary by CodeRabbit

- **Content Updates**
- Refined Partner Day event messaging and “What to expect” descriptions.
  - Simplified the hero description by removing timing-specific wording.
- Shortened inaugural-event messaging for clearer, more concise
communication.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-05 15:54:18 -07:00
shaziya 2736abf4c7 feat(www): update Partner Day at Select 2026 go page copy (#48771)
## 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?

Content update (marketing copy) for the `www` app.

## What is the current behavior?

`/go/select-2026/partner-day` has stale copy from an earlier draft of
the event: a time-boxed agenda table and a "What you'll gain" feature
grid that no longer match the approved messaging.

## What is the new behavior?

Updated copy! :)

## Additional context

- Verified the RSVP form's "Are you attending Select 2026?" select field
opens, selects, and submits correctly, with no React hydration warnings
on a clean `.next` build.
- `pnpm --filter=www exec tsc --noEmit` and `prettier --check` both pass
on the changed file.
- `pnpm build --filter=www` fails locally, but this is pre-existing and
unrelated to this change — it requires a `DOCS_GITHUB_APP_PRIVATE_KEY`
secret (for the `docs` app's federated-content prebuild step) that isn't
available in this local environment. Confirmed the identical failure
occurs on `master` with no changes applied.
2026-08-05 15:10:51 -07:00
AnaandAna 69b1f06152 docs(blog): add Enhancements for Postgres Changes launch post (#48711)
## 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?

- Adds the launch blog post for Enhancements for Postgres Changes, dated
2026-08-05
- Adds the social card and listing thumbnail for the post

## What is the current behavior?

N/A. New post.

## What is the new behavior?

- New post at `/blog/postgres-changes-filters-and-column-selection`
covering AND filter composition, the expanded filter operator set, and
column selection on Postgres Changes subscriptions
- Authored by Filipe Cabaço, using the existing `filipe` author id, so
no change to `apps/www/lib/authors.json`

## Additional context

**Please do not merge before 7:00 am PT on 2026-08-05.**

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

## Documentation

* Added a product blog post covering enhanced Postgres Changes
filtering, including comma-separated AND filters across multiple
columns.
* Documented additional filter operators and the new filter builder.
* Explained optional column selection for event payloads, permissions
and row-level security behavior, DELETE limitations, unsupported
options, client-version requirements, usage examples, and upgrade
guidance.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Ana <ana1337x@users.noreply.github.com>
2026-08-05 10:24:44 -04:00