Files
supabase/apps/studio/components/layouts/Navigation/LayoutHeader/HeaderUpgradeButton.tsx
Mert YEREKAPAN b9e83b25e1 feat(studio): adding upgrade button to header experiment (#44494)
## 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?

- Add an always-visible "Upgrade to Pro" button in the dashboard header
for free-plan users (GROWTH-615)
- Button is gated behind a PostHog experiment (`headerUpgradeCta`) with
`control` and `test` variants
- Experiment exposure is tracked for both variants; click events are
tracked when the button is clicked
- Button reuses existing `UpgradePlanButton` component for routing,
permissions, and billing logic

## What is the current behavior?

<img width="3840" height="2160" alt="Arc 2026-04-02 16 36 22"
src="https://github.com/user-attachments/assets/8a94db0c-06c8-4237-8ba5-6ac1fe111a56"
/>

## What is the new behavior?

<img width="3840" height="2160" alt="Arc 2026-04-02 16 36 12"
src="https://github.com/user-attachments/assets/0e60d834-028b-49fd-845e-ce1b4cbcc960"
/>


## Additional context

Add any other context or screenshots.


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

* **New Features**
* Added an upgrade call-to-action in the header and mobile navigation
(visible on medium+ screens in platform builds) shown to free-plan users
as part of a controlled experiment.
* The CTA records experiment exposures and sends analytics for
impressions and clicks, including the user's current plan, to measure
engagement and upgrade interest.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-03 20:51:54 +02:00

36 lines
1.4 KiB
TypeScript

import { UpgradePlanButton } from '@/components/ui/UpgradePlanButton'
import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
import { useTrackExperimentExposure } from '@/hooks/misc/useTrackExperimentExposure'
import { usePHFlag } from '@/hooks/ui/useFlag'
import { useTrack } from '@/lib/telemetry/track'
const EXPERIMENT_ID = 'headerUpgradeCta'
type HeaderUpgradeCtaVariant = 'control' | 'test'
interface HeaderUpgradeButtonProps {
className?: string
}
export const HeaderUpgradeButton = ({ className }: HeaderUpgradeButtonProps) => {
const track = useTrack()
const { data: organization } = useSelectedOrganizationQuery()
const flagValue = usePHFlag<HeaderUpgradeCtaVariant | false>(EXPERIMENT_ID)
const isFreePlan = organization?.plan?.id === 'free'
const isInExperiment = flagValue === 'control' || flagValue === 'test'
const showButton = flagValue === 'test'
// Track experiment exposure for all free-plan users in the experiment (both control and test)
const variant = isFreePlan && isInExperiment ? (flagValue as string) : undefined
useTrackExperimentExposure(EXPERIMENT_ID, variant)
if (!isFreePlan) return null
if (!showButton) return null
const handleClick = () => {
track('header_upgrade_cta_clicked')
}
return <UpgradePlanButton source={EXPERIMENT_ID} className={className} onClick={handleClick} />
}