## 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 (security hardening).
## What is the current behavior?
[PRODSEC-120](https://linear.app/supabase/issue/PRODSEC-120/mythos-ant-2026-btrnt5a3-server-action-accepts-client-controlled-crm)
— the marketing form server action accepts the full \`crm\` config
(Notion \`database_id\`, HubSpot \`formGuid\`, Customer.io \`event\`,
\`staticProperties\`, etc.) from the client, so a crafted submission can
write to any Notion database the integration token reaches, post to any
HubSpot form in the portal, or trigger arbitrary Customer.io events.
## What is the new behavior?
The client now posts only \`{ slug, formId }\` plus the field values;
\`submitFormAction\` validates the ref with Zod, looks the trusted CRM
config up from the in-process \`_go/**\` page registry via a resolver
wired up in \`instrumentation.ts\`, and fails closed if the form isn't
found. \`SectionRenderer\` also strips \`crm\` from the section before
it crosses into the client bundle (so \`database_id\` / \`formGuid\` no
longer ship in page HTML), \`getAllGoPages\` rejects any form section
with \`crm\` but no stable \`id\`, and per-submission size/character
limits were tightened.
## Additional context
Separate follow-ups (not in this PR): confirm \`NOTION_FORMS_API_KEY\`
is write-only and scoped to the forms subtree, and chase down the
\`NOTION_EVENTS_API_KEY\` validity issue raised on the Linear ticket.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
- Forms now support unique identifiers for enhanced tracking and
management
- Server-side form configuration management for improved reliability
* **Improvements**
- Enhanced form validation during page initialization to catch
configuration issues
- Improved form submission handling with better error detection and
reporting
- Strengthened form operations with fail-safe configuration resolution
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46239?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
The `_Shadcn_` suffix isn't needed anymore on `Select` components
## Solution
Remove it. No other changes
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Updated internal component architecture to standardize and simplify
the codebase. These changes improve code maintainability and consistency
across the application without affecting existing functionality or user
experience.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45988)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## 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 — anti-spam protection for all `/go` lead-gen forms.
## What is the current behavior?
The shared `MarketingForm` used by every `/go` page has no spam
protection: no honeypot, no captcha, no timing check, no dedupe. The
Datadog NYC exec dinner form was getting probed with spam submissions
([DEBR-280](https://linear.app/supabase/issue/DEBR-280/reduce-spammy-submissions-on-exec-dinner-form)).
## What is the new behavior?
Three layered defenses added to the shared `MarketingForm` +
`submitFormAction` so every `/go` form is covered:
1. **Honeypot** — hidden `website` input (off-screen, `aria-hidden`,
`tabIndex={-1}`). Server returns a fake success when filled so bots
don't probe variations. The field is stripped from the payload before
CRM fan-out.
2. **Minimum render-time check** — server rejects submissions that come
back in under 3s with a fake success.
3. **Per-session email/form dedupe** — `sessionStorage` keyed by
`formGuid`/`database_id` + email blocks double-submits; the success
state is shown without re-hitting HubSpot/Customer.io/Notion.
## Additional context
No new env vars or services required. Honeypot rejections are logged via
\`console.warn\` for monitoring.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Enhanced anti-spam protections (honeypot and minimum render time) to
block bots.
* Prevents accidental duplicate submissions within the same browser
session.
* Avoids creating duplicate contact/record entries when an existing
email is found in storage.
* **Other Improvements**
* Cleaner event/context data sent to analytics for more accurate
tracking.
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45842)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This PR migrates the JS config for Tailwind into a CSS config. As such,
all variables have been defined as CSS variables and they're using the
specialized Tailwind syntax for generating utility classes.
Beside the migration, these changes were also added:
- Added `tailwind.config.css` to few packages to make the Tailwind
Intellisense work.
- Migrated away from Radix style color classes to our defined classes,
the values will remain the same.
- Most of the CSS is generated by scripts, they'll be removed in next
PRs.
* Removed redundant `border-light` classes from several components since
it was undefined.
* Removed redundant `text-strong` classes from several components since
it was undefined.
How to test:
- Open all apps, compare the UI (mainly colors) to builds from #45417
and try to find a difference.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Harmonized color variable usages and updated UI color references
(affects palettes, charts, gradients, hero illustrations, and
scrollbars).
* Tweaked border, tab, and selection visuals across components.
* **New Features**
* Added a suite of theme animations and refined typography presets used
by site prose and docs.
* **Refactor**
* Overhauled Tailwind/theme configuration and color token generation for
more consistent theming.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## 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?
Refactor + feature
## What is the current behavior?
The AWS Activate offer page used a one-off `HubSpotFormEmbed` component
(an iframe-style HubSpot script embed) living under
`apps/www/_go/lead-gen/components/`. It was single-destination (HubSpot
only) and not reusable. Closes
[DEBR-266](https://linear.app/supabase/issue/DEBR-266).
## What is the new behavior?
Adds a reusable `MarketingForm` component to the `marketing` package
that fans out submissions to HubSpot, Customer.io, and Notion in
parallel via the existing `submitFormAction` server action. The go-page
`FormSection` is now a thin adapter on top of `MarketingForm`, and
`aws-activate-offer.tsx` uses `MarketingForm` directly. The legacy
`HubSpotFormEmbed` is deleted.
## Additional context
- `MarketingForm` is exported from `marketing` so it can be used outside
go pages.
- Customer.io / Notion fan-out for AWS Activate is wired but not yet
configured — drop in `crm.customerio` / `crm.notion` blocks once
[DEBR-265](https://linear.app/supabase/issue/DEBR-265) lands.
- The original HubSpot embed had conditional field formatting which the
new form does not replicate; verify HubSpot field internal names
(`firstname`, `lastname`, `email`, `company`, `aws_account_id`) match
the target form before merging.
- Requires `HUBSPOT_PORTAL_ID` env to point at portal `19953346` (was
previously hardcoded in the embed).
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* New reusable marketing form with responsive two-column layout,
validation, error display, success UI or redirect, optional
title/description and markdown disclaimer.
* Added URL and checkbox field types plus conditional field visibility.
* HubSpot embed accepts typed props and improves script loading with
retry and clearer error logging.
* **Refactor**
* Forms consolidated into a shared marketing module; form sections now
delegate to the shared form component.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## 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
## What is the current behavior?
`/go` page form submissions can be routed to HubSpot and Customer.io,
but there's no way to send the same data to a Notion database.
Partnerships needs Notion as a third destination.
Relates to
[DEBR-265](https://linear.app/supabase/issue/DEBR-265/notion-database-for-go-pages).
## What is the new behavior?
Adds a `notion` provider alongside `hubspot` and `customerio` in the
form CRM config. Each page can now declare:
```ts
notion: {
database_id: '21b5004b775f8058872fe8fa81e2c7ac',
columnMap: { email_address: 'email', first_name: 'first_name' },
staticProperties: { source: 'Website Go Page' },
}
```
A new `NotionClient` fetches the target database schema once per
submission to auto-detect each column's property type (`title`,
`rich_text`, `email`, `number`, `select`, etc.) so the config stays a
plain string→string map. Unknown columns are silently skipped. The
submit action reads `NOTION_API_KEY` from env and dispatches in parallel
with the existing providers.
## Additional context
- New env var required on Vercel: `NOTION_API_KEY` (a Notion internal
integration token with write access to the target database).
- Simplified `CRMConfig` from a discriminated-union-of-all-combinations
to a plain object with optional providers; the "at least one provider"
invariant still lives in the Zod schema refinement. This avoided a 2^3 -
1 = 7 member union and a generic `CRMClient<T>` whose call site was
already casting to `any`.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added Notion as a CRM provider for form submissions with schema-backed
mapping, validation, and automatic creation of Notion database pages.
* Exposed a typed Notion form config for configuration and validation;
example lead-gen form includes a Notion mapping.
* **Bug Fixes / Improvements**
* Simplified CRM option handling and made submission behavior clearer.
* HubSpot submissions now URI-encode identifiers to avoid endpoint
errors.
* Improved Notion request handling, caching, and error reporting; Notion
sends in parallel when configured.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This PR migrates the whole monorepo to use Tailwind v4:
- Removed `@tailwindcss/container-queries` plugin since it's included by
default in v4,
- Bump all instances of Tailwind to v4. Made minimal changes to the
shared config to remove non-supported features (`alpha` mentions),
- Migrate all apps to be compatible with v4 configs,
- Fix the `typography.css` import in 3 apps,
- Add missing rules which were included by default in v3,
- Run `pnpm dlx @tailwindcss/upgrade` on all apps, which renames a lot
of classes
- Rename all misnamed classes according to
https://tailwindcss.com/docs/upgrade-guide#renamed-utilities in all
apps.
---------
Co-authored-by: Jordi Enric <jordi.err@gmail.com>
This PR preps the monorepo for a migration to Tailwind v4:
- Bump all Tailwind dependencies and libraries to the latest possible
version, while still compatible with Tailwind 3.
- Cleans up obsolete Tailwind 3 specific options and configs.
- Cleans up unused CSS files and fixes the CSS imports.
- Migrates all `important` uses in `@apply` lines to using the `!`
prefix.
- Move `typography.css` to the `config` package and import it from the
apps.
- Migrated all occurrences of `flex-grow`, `flex-shrink`,
`overflow-clip` and `overflow-ellipsis` since they're deprecated and
will be removed in Tailwind 4.
- Make the default theme object typesafe in the `ui` package.
- Migrate all `bg-opacity`, `border-opacity`, `ring-opacity` and
`divider-opacity` to the new format where they're declared as part of
the property color.
- Bump and unify all imports of `postcss` dependency.
## Problem
We'd like to update react to `19` but many of our dependencies don't
support it.
## Solution
Update those dependencies. This PR focuses on `react-markdown`
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Upgraded react-markdown to 10.1.0 (and remark-gfm to 4.0.0) across
projects for improved Markdown support.
* **Style**
* Adjusted Markdown rendering so typography and spacing are applied via
surrounding containers, improving consistent styling across docs and UI.
* **New Content**
* Added a new RSS feed item for a recent blog post.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
### FAQ (`type: 'faq'`)
Accordion-style FAQ with expand/collapse. Each item has a `question` and
`answer`. Click to toggle — only one open at a time.
<img width="1309" height="610" alt="Screenshot 2026-03-13 at 17 31 31"
src="https://github.com/user-attachments/assets/289c8a12-3835-4f64-bbe6-fb7095df4e7c"
/>
### Code Block (`type: 'code-block'`)
Syntax-highlighted code display using shiki with custom Supabase
dark/light themes. Supports:
- **Single file** — `code` + optional `filename` + `language`
- **Multi-file** — `files: [{ filename, code, language }]` with
clickable tabs
- Line numbers via CSS counters
- All highlighting runs at build time (server component), only tab
switching is client-side
<img width="1283" height="415" alt="Screenshot 2026-03-13 at 17 32 07"
src="https://github.com/user-attachments/assets/9cc9a215-d5c9-47c9-8e21-c1dd3beca4ba"
/>
### Steps (`type: 'steps'`)
Numbered step-by-step guide with a vertical timeline connector. Each
item has `title` and either a plain `description` string or a `content`
slot accepting any React node (e.g. images, code blocks).
<img width="1119" height="810" alt="Screenshot 2026-03-13 at 17 32 20"
src="https://github.com/user-attachments/assets/cb67aaab-9ed4-42e2-bf1c-8d836024e469"
/>
### Quote (`type: 'quote'`)
Centered testimonial block with `quote`, `author`, optional `role`, and
optional `avatar` image.
<img width="1095" height="238" alt="Screenshot 2026-03-13 at 17 32 37"
src="https://github.com/user-attachments/assets/356a39ca-9f65-4414-bf77-6060993594a4"
/>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES/NO
## What kind of change does this PR introduce?
Bug fix, feature, docs update, ...
## What is the current behavior?
Please link any relevant issues here.
## What is the new behavior?
Feel free to include screenshots if it includes visual changes.
## Additional context
Add any other context or screenshots.
## Summary
- Add contest rules legal page (`/go/contest-rules`) with official
sweepstakes rules
- Add executive dinner landing page (`/go/stripe/exec-dinner`) with RSVP
form backed by HubSpot and Customer.io
- Add executive dinner thank-you page
(`/go/stripe/exec-dinner/thank-you`)
- Add Stripe Sessions contest page (`/go/stripe/contest`) for iPhone 17
Pro Max sweepstakes
## Notes
- HubSpot `formGuid` on the exec dinner page needs to be replaced with
the real value before going live
- Customer.io `staticProperties` support is needed to send `event_name`
as a track property (see TODO comment in exec dinner page)
- iPhone image placed at
`public/images/landing-pages/stripe-sessions/iphone17-pro-max.png`
## Test plan
- [ ] Verify all four pages render correctly at their respective slugs
- [ ] Test RSVP form submission on exec dinner page
- [ ] Confirm contest rules page content matches official legal rules
- [ ] Verify iPhone image renders in contest page hero
- [ ] Check mobile responsiveness on all pages
---------
Co-authored-by: Alan Daniel <stylesshjs@gmail.com>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES/NO
## What kind of change does this PR introduce?
Bug fix, feature, docs update, ...
## What is the current behavior?
Please link any relevant issues here.
## What is the new behavior?
Feel free to include screenshots if it includes visual changes.
## Additional context
Add any other context or screenshots.
Co-authored-by: Jordi Enric <37541088+jordienr@users.noreply.github.com>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
New Go landing page for the upcoming Bolt webinar. This is where we will
direct customers who want to learn more to go to request a meeting.
---------
Co-authored-by: Alan Daniel <stylesshjs@gmail.com>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES/NO
## What kind of change does this PR introduce?
Bug fix, feature, docs update, ...
## What is the current behavior?
Please link any relevant issues here.
## What is the new behavior?
Feel free to include screenshots if it includes visual changes.
## Additional context
Add any other context or screenshots.