feat(landing): 3-way CRO copy A/B/n on the hero (exp-landing-copy)
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled

Meta Ads traffic converts to signup well below expectation. Same design, three
hero-copy variants (lossPill + title + subtitle) behind the exp-landing-copy
multivariate flag, measuring user_signed_up (experiment 83160):
- control:   current "find the right part instantly" (feature / accuracy)
- variant_a: "end wrong-part returns" (ROI / business-outcome + risk reversal)
- variant_b: "find it in seconds, free, no card" (risk reversal / signup friction)

useFeatureFlag on the index hero, undefined -> control. B2B-safe copy
("customer vehicle", not "your car"). Stays draft until prod, then launch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-09 12:29:37 +03:00
parent 5de2d12ad5
commit 3325747428
4 changed files with 21 additions and 3 deletions

View File

@@ -12,6 +12,7 @@ import { vi } from "vitest";
// Mock the PostHog capture function
vi.mock("@/lib/posthog", () => ({
capture: vi.fn(),
subscribeFeatureFlag: vi.fn(() => () => {}),
}));
// Mock the API client used for VIN decode

View File

@@ -158,6 +158,7 @@ const RemotionEcommercePlayer = lazy(() =>
),
);
import { useAuth } from "@/hooks/use-auth";
import { useFeatureFlag } from "@/hooks/use-feature-flag";
import { usePageMeta } from "@/hooks/use-page-meta";
import { ApiError, api } from "@/lib/api-client";
import { useTranslation } from "@/lib/i18n";
@@ -253,6 +254,10 @@ export const Route = createFileRoute("/")({
export function HomePage() {
const { t } = useTranslation();
// Landing-copy A/B/n (exp-landing-copy): SAME design, CRO copy variants for the
// hero pill/title/subtitle. undefined → control. Primary metric: user_signed_up.
const landingCopy = useFeatureFlag("exp-landing-copy");
const copyV = landingCopy === "variant_a" ? "A" : landingCopy === "variant_b" ? "B" : "";
usePageMeta({
title: t("landing.meta.title"),
@@ -887,7 +892,7 @@ export function HomePage() {
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-destructive/60 opacity-75" />
<span className="relative inline-flex size-2 rounded-full bg-destructive" />
</span>
{t("landing.hero.lossPill")}
{t(`landing.hero.lossPill${copyV}`)}
</div>
{/* Social proof badge */}
@@ -922,11 +927,11 @@ export function HomePage() {
</div>
<h1 className="mt-6 font-[family-name:var(--font-display)] text-4xl font-bold leading-[1.1] tracking-tight sm:text-5xl lg:text-7xl">
{t("landing.hero.title")}
{t(`landing.hero.title${copyV}`)}
</h1>
<p className="mx-auto mt-6 max-w-2xl text-base text-muted-foreground sm:text-lg">
{t("landing.hero.subtitle")}
{t(`landing.hero.subtitle${copyV}`)}
</p>
{/* VIN Input */}