Commit Graph

21 Commits

Author SHA1 Message Date
Jeremias Menichelli 41962e6bf5 feat(Docs): Implement Accept header for agents markdown requests (#43745) 2026-03-13 13:32:40 +01:00
Jeremias Menichelli 8b4bf646fc feat(Docs): Add copy as markdown and AI tools to guide (#43355) 2026-03-04 16:31:02 +01:00
Ivan Vasilov 87ee98ed3d fix(proxy): remove first-referrer cookie stamping from Studio and Docs middleware (#43190)
Summary
- Reverts the middleware changes to `apps/studio` and `apps/docs` from
#43153 that caused full page reloads on every client-side navigation in
Studio
- Root cause: broadening the `middleware` matchers to match all routes
and returning `NextResponse.next()` unconditionally interferes with
client-side navigation in the multi-zone production setup (`www` proxies
`/dashboard/*` → Studio, `/docs/*` → Docs)
- Cookie stamping is unnecessary in Studio and Docs because `apps/www`
sits in front of both apps in production and already handles
first-referrer cookie attribution for all incoming traffic
- The `apps/www` middleware, packages/common cookie utilities, and
telemetry changes from #43153 are left intact

Test plan
- Verify client-side navigation works without full page reloads in
Studio (production or preview deploy)
- Verify first-referrer cookie is still stamped via `www` middleware on
initial visit
2026-02-25 20:56:50 +01:00
Sean Oliver 75ec7c6e6b feat(growth): re-land first-referrer cookie attribution with fixed middleware matchers (#43153)
## Summary

Re-lands the first-referrer cookie feature from #42768 (reverted in
#43129) with middleware matcher fixes that prevent Studio traffic
interference.

**Tracks:** [GROWTH-651](https://linear.app/supabase/issue/GROWTH-651)

## What changed

New shared module in `packages/common/first-referrer-cookie.ts` that
handles stamping and parsing a first-referrer cookie (referrer, UTMs,
click IDs, landing URL). Each app's middleware calls
`stampFirstReferrerCookie` on the edge response — www and docs are the
primary entry points, Studio is a fallback for direct visits with UTMs.

On the telemetry side, `handlePageTelemetry` now takes an options object
instead of positional args, reads the cookie on initial pageview, and
overrides the referrer if the cookie captured an external source but the
current referrer is internal (i.e., the user navigated cross-app). Also
sends `first_referrer_cookie_present`/`consumed` properties so we can
observe the handoff in PostHog.

The docs middleware matcher was broadened from `/reference/:path*` to
all docs pages so we stamp cookies site-wide, not just on reference
paths.

## Root cause of original revert

Two layers:

1. **Matcher gap**: www middleware ran on `/dashboard/*` traffic in prod
due to Vercel Multi-Zone architecture (www is the gateway for
`supabase.com`, proxying `/dashboard` → Studio, `/docs` → Docs).
Middleware runs *before* rewrites, so www middleware executed on all
proxied traffic.

2. **`_next/data` interception**: The matcher didn't exclude
`_next/data` paths. Client-side navigation in Next.js fetches JSON via
`/_next/data/...` — middleware intercepted these, returned
`NextResponse.next()` with cookie mutations (which processes through the
middleware response pipeline), and this interfered with the JSON
responses, causing full page reloads in the SQL editor.

## How this PR fixes it

| Fix | Detail |
|---|---|
| Exclude `_next/data` | All three matchers (`www`, `docs`, `studio`)
exclude `_next/data` via negative lookahead |
| Exclude `dashboard` + `docs` from www | www middleware no longer runs
on proxied app traffic |
| `/api/` path guard in Studio | Broadened matcher requires explicit
path check for API route filtering |
| `NextResponse.next()` semantics | Cookie stamping only happens on
matched paths; unmatched paths never enter middleware |

### `NextResponse.next()` vs `undefined` nuance

Returning an explicit `NextResponse.next()` with cookie mutations
processes through Next.js's middleware response pipeline (headers are
merged, cookies are set). Returning `undefined` (i.e. the request never
matches the matcher) lets Next.js handle the request completely
untouched. The matcher exclusions ensure `_next/data` and proxied app
paths never enter middleware at all.

## Testing

-  22 unit tests for shared cookie utilities (all pass)
-  Studio prod build succeeds, middleware recognized as `ƒ Proxy
(Middleware)`
-  Playwright validation: client-side navigation works across 3 page
transitions, `_next/data` requests return 200 OK without middleware
interception, no full-page reloads
-  www/docs SSG builds require platform backend services (expected —
same as master)
2026-02-25 09:24:32 -08:00
Ivan Vasilov 85e6b1143f chore: Revert "fix: persist first referrer across app boundaries (#42768)" (#43129)
This reverts commit
https://github.com/supabase/supabase/commit/04e63dfb2e00c43f8c57e538b8056aa647f4e5b4
since it was causing the Studio app to rerender the full page on every
link navigation.
2026-02-24 11:56:44 +00:00
Sean Oliver 04e63dfb2e fix: persist first referrer across app boundaries (#42768)
## Summary

Fixes GROWTH-625.

Preserves first-touch attribution across app boundaries by persisting
external referrer context at the edge and consuming it on Studio's
initial pageview.

When users come from an external source to www/docs and then navigate to
Studio, Studio often only sees the internal `supabase.com` hop. This
change preserves the original external context so first-touch
attribution is retained.

## What changed

- **Shared first-referrer cookie utilities**
(`packages/common/first-referrer-cookie.ts`):
- `isExternalReferrer`, `buildFirstReferrerData`,
`serializeFirstReferrerCookie`, `parseFirstReferrerCookie`
- `hasPaidSignals` — detects click IDs (gclid, fbclid, etc.) and paid
utm_medium values
- `shouldRefreshCookie` — centralizes stamp-or-skip decision for all
apps
- `stampFirstReferrerCookie` — shared middleware helper used by all apps
(extracted from duplicated inline logic)
- **Edge middleware on all apps** — stamps cookie for external visitors,
refreshes on paid signals:
  - `apps/www/middleware.ts` (simplified to use shared helper)
  - `apps/docs/middleware.ts` (simplified to use shared helper)
  - `apps/studio/proxy.ts` (integrated into existing proxy file)
- **Docs middleware matcher** — broadened from `/reference/:path*` to
all non-static paths so the first-referrer cookie is stamped on all docs
pages, not just reference paths
- **Telemetry** — Studio consumes cookie on initial pageview
(`packages/common/telemetry.tsx`). `handlePageTelemetry` refactored from
7 positional params to an options object for readability.
- **Tests** — 22 unit tests covering all utilities and edge cases
(including direct-navigation scenario)

## Behavior

- Writes `_sb_first_referrer` cookie when:
  - cookie is not already set and request has an external referrer, OR
- cookie exists but incoming URL has paid traffic signals (click IDs or
paid utm_medium)
- Cookie: 365-day TTL, `domain=supabase.com`, `sameSite=lax`,
`secure=true` in production
- On first Studio pageview, if current referrer is internal and cookie
has external context:
  - use persisted external referrer
  - apply persisted UTM/click-id/landing-url attribution props
- Measurement properties: `first_referrer_cookie_present`,
`first_referrer_cookie_consumed`

## Manual testing

1. Visit `supabase.com/pricing?utm_source=google&utm_medium=cpc` from an
external referrer (or use DevTools to set a `Referer` header)
2. Check `_sb_first_referrer` cookie is set in Application > Cookies
3. Navigate to Studio (`supabase.com/dashboard`)
4. In PostHog (or browser network tab), verify the first `$pageview`
event has:
   - `first_referrer_cookie_present: true`
   - `first_referrer_cookie_consumed: true`
   - `$utm_source: "google"`, `$utm_medium: "cpc"`
   - `$referrer` points to the external source, not `supabase.com`
5. Verify subsequent route changes do NOT include
`first_referrer_cookie_*` properties

## Review feedback addressed

- Added `secure: true` flag on production cookies (Pam's first comment)
- Fixed inaccurate JSDoc on `utms` field — keys retain `utm_` prefix
(Pam's fourth comment)
- Added test coverage for edge cases: malformed URLs, multi-cookie
headers, http:// referrers (Pam's sixth comment)
- Docs matcher broadening: fast-path exit on cookie-exists check keeps
overhead minimal, exclusion list is correct
- Extracted shared middleware helper to eliminate duplication across 3
apps
- Refactored `handlePageTelemetry` from positional params to options
object
- Removed redundant null check in `hasPaidSignals`
- Added direct-navigation test case
- Deleted dead `apps/learn/middleware.ts`
- Fixed studio build: integrated cookie stamping into existing
`proxy.ts` (Next.js 16 rejects both middleware.ts and proxy.ts)

---------

Co-authored-by: pamelachia <26612111+pamelachia@users.noreply.github.com>
Co-authored-by: Pamela Chia <pamelachiamayyee@gmail.com>
2026-02-23 13:31:39 -08:00
Charis f5ff10e195 refactor,tests(support form) (#39410)
* refactor: refactor support form

Refactor support form to make it easier to maintain:
- Split up large components into smaller components and hooks
- Lift state up so we don't have to do complex child/parent
state-syncing via useEffect
- Use nuqs parsing for consistent serialization/deserialization of
support form prefilled fields

* test: support form

Add comprehensive tests for support form

* fix(support form): project and org empty state

* Nit clean up

* More clean up

* cleannnn

* fix(support form): allow case-insensitive category in url

* clean(support form tests): remove unused param

* fix(support form): incorrect logic for sending affected services in payload

* clean(support form): use NO_ORG_MARKER and NO_PROJECT_MARKER instead of strings

* fix(support form): don't show upgrade cta if already on enterprise

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2025-10-14 11:04:33 +08:00
Charis eed0f6e7ce fix: don't render hidden pages (#38477)
* fix: remove hidden guide pages from render

Guide pages hidden from nav are still rendered. This change removes them
from both build-time and on-demand rendering.

* fix: build llms script

The build llms script does not run in an environment where React is
available, so it must import from 'common/enabled-features', not from
'common', to avoid errors.

* fix: don't render hidden reference pages

Similar to guides, but for client SDK references. If a page is hidden
from the navigation (its feature flag is toggled off), don't render it
at all. This includes (a) at build time, (b) at request time, and (c) at
crawler request time.

* fix: types
2025-09-08 13:05:38 -04:00
Charis 39a12342ea fix (docs): middleware rewrites for reference pages (#35201)
Before:

There was a bug with middleware rewrites for reference pages without
crawler versions (basically all references except the client SDKs).
There was a branch that was not handled (the requesting user agent is a
a bot, but the reference is not a client SDK), so it failed through to
the base case of NextResponse.next(), which 404s as that page does not
exist for a path like /reference/api/v1-deploy-a-function

After:

Fixed the branch. If all of the following are true:

- Is a reference page
- Requesting user agent is a bot
- Reference is not a client SDK

Then it should follow the same path as a non-bot request, because there
is no bot-specific version. That means it should be rewritten to teh
slugless page: /reference/api/v1-deploya-function => /reference/api
2025-04-22 10:14:02 -04:00
Charis 4da23b2992 fix(docs): prevent error on /docs/reference path (#29345) 2024-09-17 10:59:08 -04:00
Charis 11e19ff29f refactor(docs): convert self-hosting to app router (#29268)
* chore(docs,refs): prebuild self-hosted ref data

Pregenerate self-hosted ref data files, in the style of the client lib,
Management API, and CLI references. Preparatory step for migrating the
self-hosted references to App Router.

* refactor(docs): convert self-hosting to app router

Convert self-hosting reference pages to App Router.

* fix(docs,sitemap)
2024-09-13 09:45:55 -04:00
Charis 33ede6f893 refactor(docs): convert management api reference to app router (#29146)
* chore(docs): preprocess management api specs

In preparation for App Router migration of Management API reference,
preprocess the Management API spec (both OpenAPI spec and common
sections), and write the processed data to file, in the style of the
other pregenerated reference data.

Details:

- Split reference section generation into separate functions for SDK, CLI, and API
- Add new function to generate API reference sections from OpenAPI spec
- Introduce mapEndpointsById function to create a map of API endpoints
- Update run function to execute all reference generation tasks in parallel
- Import necessary new dependencies and types

* refactor(docs): migrate management api reference to app router

* fix(docs): statically build management api reference page

* fix(docs): minor styling issues
2024-09-11 13:53:45 -04:00
Charis 84a8fa7ac3 refactor(docs): migrate cli reference to app router (#29117) 2024-09-06 09:22:25 -04:00
Charis fc164b5d07 Refactor/app router refs (#28095)
Migrates client SDK References to App Router. (Management and CLI API references aren't migrated yet, nor are self-hosting config references.)

Some notes:

Big changes to the way crawler pages are built and individual section URLs (e.g., javascript/select) are served. All of these used to be SSG-generated pages, but the number of heavy pages was just too much to handle -- slow as molasses and my laptop sounded like it was taking off, and CI sometimes refuses to build it all at all.

Tried various tricks with caching and pre-generating data but no dice.

So I changed to only building one copy of each SDK+version page, then serving the sub-URLs through a response rewrite. That's for the actual user-visible pages.

For the bot pages, each sub-URL needs to be its own page, but prebuilding it doesn't work, and rendering on demand from React components is too slow (looking for super-fast response here for SEO). Instead I changed to using an API route that serves very minimal, hand-crafted HTML. It looks ugly, but it's purely for the search bots.

You can test what bots see by running curl --user-agent "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" <URL_OF_PAGE>

Also added some smoke tests to run against prod for the crawler routes, since we don't keep an eye on those regularly, and Vercel config changes could surprise-break them. Tested the meta images on Open Graph and all seems to work fine.

With this approach, full production builds are really fast: ~5 minutes

Starts using the new type spec handling, which is better at finding params automatically, so I could remove some of the manually written ones from the spec files.
2024-08-13 16:12:59 -04:00
Kevin Grüneberg a56ff72d16 chore: upgrade isbot (#22248) 2024-03-26 13:38:33 +00:00
Joseph Schultz 7c127c8f64 Begin C# Documentation based off Flutter v1 docs 2022-12-23 16:52:20 -06:00
Terry Sutton 1e242b16cf Add crawler slugs for all libs 2022-12-11 10:30:27 -03:30
Terry Sutton 956d42896c Just run middleware for bots 2022-12-11 09:16:51 -03:30
Terry Sutton 37a627eb99 Trying js middleware 2022-12-11 09:08:06 -03:30
Terry Sutton 65a39919d0 Remove middleware again 2022-12-09 11:43:46 -03:30
Terry Sutton c425d775bc Fix ts errors 2022-12-09 09:47:11 -03:30