From 4309035edde6716915045d5633bcad247bc68747 Mon Sep 17 00:00:00 2001 From: eldadfux Date: Fri, 1 May 2026 06:21:45 -0400 Subject: [PATCH 1/2] feat(statsig): add best_cta experiment and sync nav CTA Add Statsig experiment best_cta with cta param for hero primary button. Wire SSR bundle, bootstrap, client exposure, and hero_cta URL override. Align desktop nav, mobile header, and custom hero with heroCta from load. Made-with: Cursor --- src/lib/components/IsLoggedIn.svelte | 9 +++- .../homepage-variations/custom-hero.svelte | 18 +++++--- src/lib/components/layout/site-header.svelte | 8 +++- src/lib/layouts/Main.svelte | 4 +- src/lib/statsig/constants.ts | 2 + .../experiments/marketing-hero-client.ts | 16 +++++++- .../statsig/experiments/marketing-hero-ids.ts | 2 + .../experiments/marketing-hero-server.ts | 41 +++++++++++++++++-- src/lib/statsig/hero-query-overrides.ts | 26 ++++++++++-- src/lib/statsig/hero-statsig.server.ts | 1 + .../(marketing)/(components)/hero.svelte | 25 ++++++++--- src/routes/(marketing)/+page.server.ts | 22 ++++++---- src/routes/(marketing)/+page.ts | 5 ++- 13 files changed, 148 insertions(+), 31 deletions(-) diff --git a/src/lib/components/IsLoggedIn.svelte b/src/lib/components/IsLoggedIn.svelte index df8af8a76d..cd79d79ca8 100644 --- a/src/lib/components/IsLoggedIn.svelte +++ b/src/lib/components/IsLoggedIn.svelte @@ -1,7 +1,9 @@ diff --git a/src/lib/components/homepage-variations/custom-hero.svelte b/src/lib/components/homepage-variations/custom-hero.svelte index dd3b57c6b1..07d3c2c052 100644 --- a/src/lib/components/homepage-variations/custom-hero.svelte +++ b/src/lib/components/homepage-variations/custom-hero.svelte @@ -4,7 +4,7 @@ import { PUBLIC_APPWRITE_DASHBOARD } from '$env/static/public'; import { onMount } from 'svelte'; import { trackEvent } from '$lib/actions/analytics'; - import { DEFAULT_HERO_SUBTITLE, DEFAULT_HERO_TITLE } from '$lib/statsig/constants'; + import { DEFAULT_HERO_CTA, DEFAULT_HERO_SUBTITLE, DEFAULT_HERO_TITLE } from '$lib/statsig/constants'; import { initStatsig, whenStatsigReady } from '$lib/statsig/client'; import { readMarketingHeroExperimentsForExposure } from '$lib/statsig/experiments/marketing-hero-client'; import { @@ -22,7 +22,7 @@ title = DEFAULT_HERO_TITLE, subtitle = DEFAULT_HERO_SUBTITLE, showDashboard = true, - ctaLabel = 'Start building for free', + ctaLabel = DEFAULT_HERO_CTA, ctaHref = PUBLIC_APPWRITE_DASHBOARD, heroLayout = 0 } = $props<{ @@ -37,12 +37,14 @@ /** Same client hydration path as marketing `hero.svelte` (Statsig + query overrides). */ let clientHeroLayout = $state(undefined); let clientHeroSubtitle = $state(undefined); + let clientHeroCta = $state(undefined); const resolved = $derived( resolveHeroQueryOverrides(building ? new URLSearchParams() : page.url.searchParams, { heroLayout: clientHeroLayout ?? heroLayout, heroSubtitle: clientHeroSubtitle ?? subtitle, - heroTitle: title + heroTitle: title, + heroCta: clientHeroCta ?? ctaLabel }) ); @@ -64,10 +66,11 @@ void whenStatsigReady().then((client) => { if (!client) return; - const { heroSubtitle: nextSubtitle, heroLayout: nextLayout } = + const { heroSubtitle: nextSubtitle, heroLayout: nextLayout, heroCta: nextCta } = readMarketingHeroExperimentsForExposure(client, { heroSubtitle: subtitle, - heroLayout + heroLayout, + heroCta: ctaLabel }); if (nextSubtitle !== subtitle) { clientHeroSubtitle = nextSubtitle; @@ -75,6 +78,9 @@ if (nextLayout !== heroLayout) { clientHeroLayout = nextLayout; } + if (nextCta !== ctaLabel) { + clientHeroCta = nextCta; + } }); }); @@ -170,7 +176,7 @@ class={layoutAside ? 'w-full! lg:w-fit!' : 'w-full! sm:w-fit!'} onclick={() => { trackEvent(`main-get_started_btn_hero-click`); - }}>{ctaLabel}{resolved.heroCta} diff --git a/src/lib/components/layout/site-header.svelte b/src/lib/components/layout/site-header.svelte index 49d313caa5..dccf5d3256 100644 --- a/src/lib/components/layout/site-header.svelte +++ b/src/lib/components/layout/site-header.svelte @@ -1,7 +1,13 @@