Reads from /api/ab-stats (D1-backed). Auto-refreshes every 30 seconds while open.
Your assigned variant: checking…
The two variants
Variant A (control) — primary: "Call or Text 702-496-4214"; secondary: "Schedule a Free Pickup" (links to /free-book-pickup-albuquerque).
Variant B (action-first) — primary: "Get Free Book Pickup — 702-496-4214"; secondary: "Text NMLP Now" (links to sms:+17024964214).
How it's tracked
Two channels:
Server-side counters — every assignment and click POSTs to /api/ab-event, which writes to D1. /api/ab-stats reads aggregated counts. That's what this page shows.
Google Analytics 4 — same events fire to GA4 as ab_cta_assignment (params: ab_variant, ab_page) and ab_cta_click (params: ab_variant, ab_action, ab_page). Filter by these in GA4 Explore for sophisticated analysis.
How to read the result
What "winning" means
Compare ctr_overall (total clicks ÷ assignments) between the two variants. Higher is better. The variant with more call_click + sms_click + schedule_click per assignment is the winner. Ignore noise until each variant has at least 200 assignments — anything less is too small for confident conclusions.
Statistical-significance shortcut
Rule of thumb at small N: if absolute CTR difference is <3 percentage points and you have under 500 assignments per variant, call it inconclusive. If absolute difference is >5 percentage points and you have 200+ assignments per variant, you have directional signal. For real significance testing, paste both assignment and total_clicks counts into a two-proportion z-test (any online calculator works).
When to call it
Either (a) one variant is clearly winning at 500+ assignments per variant and you're ready to ship the winner site-wide, or (b) results are flat at 1,000+ assignments per variant — in which case the copy variants don't matter and you should test something more substantial.
How to ship the winner
When a winner is clear, edit /ab-cta.js — change the getOrAssignVariant function to always return the winning variant. Or remove the script entirely and hard-code the winning copy into the hero CTA template across the 14 pages. Then deploy.
How to reset the test
Wipe the D1 table and let it re-seed:
npx wrangler d1 execute nmlp-db --remote --command "DELETE FROM ab_events;"