Every "Free Trial" CTA now opens an on-site popup, captures the lead (name, email, phone), pushes them into PushPress via Zapier, and redirects them into the existing PushPress booking flow. Anyone who doesn't progress shows up on the Lead Chase dashboard for a phone call.
🎉 ZERO new Zaps required
We capture lead details on our popup → write to TrialLead → redirect them to PushPress's own signup flow (with name + email pre-filled in the URL). PushPress handles its own account creation. Your existing linkTrialAttribution, referralAttended and markMemberConversion Zaps fire when they finish PushPress and mirror back to TrialLead. No new Zaps anywhere.
Lead capture — done
Popup captures name/email/phone + "who is this for?" (self / child / teen). For kids/teens we explicitly ask for the PARENT'S phone — so phone numbers always land in Klaviyo.
PushPress handover — done
After submit, popup redirects to PushPress with ?first_name=...&email=... pre-filled. User finishes the proper PushPress flow (including parent/child structure for kids).
Status mirror back to TrialLead — done
Your existing trial-signup, check-in and paid-conversion Zaps already feed the Lead Chase dashboard. Match key is email.
Rewrite the PushPress welcome email
Replace app-download CTA with "Book your free class" + explain the one-time-code login.
Update Google Ads conversion
The new on-domain generate_lead event fires when the popup is submitted. Add it as a Google Ads conversion. See section below.
Slot the recovery sequence into your existing Klaviyo flows
You said you already have several flows — slot the T+0 / T+1hr / T+24hr touches into the right ones (template below).
Open /lead-chase every morning
Work through the "Call today" bucket. This is the highest-ROI 15 minutes of your day.
Leads in CRM
2–3×
We now capture people who'd previously click "Free Trial" but never finish PushPress.
Trial classes booked
+10–20%
The popup adds a step; the Klaviyo follow-up + phone chase recovers most who'd otherwise be lost.
Members from chase calls
+5–10/mo
Realistic. Call ~30 leads/week from the dashboard, expect 1-in-10 to book.
USER taps "Book Free Trial" anywhere on site
│
▼
┌─────────────────────┐
│ Popup opens │ ← <TrialLeadPopup /> in layout
│ 4 fields, no nav │
└─────────┬───────────┘
│ submit
▼
┌─────────────────────────────┐
│ /functions/createTrialLead │
│ 1. dedupe email (24h) │
│ 2. write TrialLead row │
│ 3. POST to Zap A │
│ 4. fire GA4 generate_lead │
└──────────┬──────────────────┘
│
┌──────────┴──────────┐
▼ ▼
USER redirected Zap A "Catch Hook"
to PushPress │
plan URL ▼
│ PushPress "Find Person"
▼ │
PushPress one-time ▼ (if not found)
code login → PushPress "Create a Person"
pick a class │
│ ▼
│ PushPress has a lead with full attribution
│
▼ (any events from now on…)
PushPress fires triggers:
• New Person → Zap B → updateTrialLeadStatus(person_created)
• Subscription to free trial → Zap B → trial_registered
• Check-In → Zap B → checked_in
• Paid subscription → Zap B → subscribed_paid
│
▼
/lead-chase dashboard
shows them in the right bucketThe dashboard automatically categorises every lead into one of these buckets based on the data we receive back from PushPress via Zap B.
🔴 Call today
Filled the popup but never registered for the free trial plan in PushPress and submitted 2+ hours ago. They bailed somewhere between our form and PushPress's one-time-code login. Hot lead. Call immediately.
🟠 No-show — call this week
Registered for the free trial plan but never showed up to a class in 7+ days. Friendly check-in: "we noticed you didn't make it in — want to pick another time?"
🟢 Attended — close the sale
Came to a trial class but didn't sign up for a paid membership within 3 days. Highest-ROI call of the three. They've already met you.
How "called today" works
Each row has Call / Text / Email buttons + outcome logging (Booked, No answer, Voicemail, Reschedule, Not interested, Wrong number). After logging an outcome, the row hides for 24 hours so you don't accidentally call the same person twice. Toggle off "Hide called today" to see everything.
Your old conversion event likely fired on the PushPress booking page (or on click). With the new flow, we should fire conversions from our domain on the popup submit — far more reliable and earlier in the funnel.
What the code now sends
When the popup is submitted, we fire:
✅ Decision: direct via gtag (not GA4 import)
Real-time signal to Smart Bidding (vs 24–48hr lag for GA4 import), simpler attribution, fewer hops. The generic GA4 generate_lead event still fires too — so GA4 import remains available as a fallback if you ever want it.
Step 1 — Create the conversion action in Google Ads
basingstokeboxing.com) and click Scan.Trial Lead — Popup Submit5 GBPStep 2 — Get the conversion ID
AW-XXXXXXXXX/YYYYYYY format).Step 3 — Paste the ID into our config (this is where it goes live on the site)
lib/leadCaptureConfig.js.GOOGLE_ADS_CONVERSION block:AW-XXXXXXXXX/YYYYYYY string between the quotes on the id line.'' (empty) if you want to pause the direct fire — the generic generate_lead event still fires for GA4 reports.Step 4 — Verify it's working (do this within an hour of going live)
basingstokeboxing.com/?gclid=test123 in an incognito window.generate_lead (GA4)conversion with your AW-… send_toNo recent conversions → Recording conversions within ~30 mins.Step 5 — Clean up your existing conversions
You probably still have older click-based conversions configured. Tidy them up so Smart Bidding only optimises the right ones:
free_trial_booking_clicked (clicks, not submits) → set to Secondary. Don't delete — keep it as a backup signal.trial_registered, trial_attended, member_converted) as Primary.Why this is better
The old free_trial_booking_clicked fired on click — but only ~22% of clickers actually finished PushPress, so Google was optimising for clickers, not signers. The new generate_lead only fires when someone actually completes the form. Higher signal-to-noise. Combined with the offline upload of real paying members, Google has the full quality signal.
The full conversion cascade (recommended)
You already upload offline conversions via Zapier for trial signup, attendance and paid membership. Adding the on-site generate_lead at the front gives Smart Bidding a fast learning signal — without it, the algorithm waits 7–14 days for paid signals and burns budget on low-quality clicks in the meantime.
| Event | Fires when | Source | Value | Type |
|---|---|---|---|---|
generate_lead | Popup submitted (instant) | On-site (gtag) | £5 | Primary |
trial_registered | Finishes PushPress signup | Offline (Zapier) | £15 | Primary |
trial_attended | Shows up to first class | Offline (Zapier) | £25 | Primary |
member_converted | Buys paid membership | Offline (Zapier) | £300 | Primary |
Why £5, not £0?
Google ignores £0 conversions when calculating Smart Bidding signals. £5 is enough to register interest but low enough that it can't swamp the higher-value paid signal.
Why £300 for a member?
Rough 3-month LTV (£100/mo × ~3 months avg tenure at the top of funnel). Tweak based on your actual numbers from /channel-roi.
All 4 set as Primary?
Yes — Google Ads sums Primary conversion values for bidding. Setting all four as Primary lets it optimise toward the full funnel value, weighted naturally by the £-amount.
Dedupe between online + offline?
Not needed — these are separate conversion actions. Same person hits each one once max. Google counts them all because each represents real funnel progress.
GCLID matching — already wired ✅
The popup captures gclid + fbclid on submit → linkTrialAttribution matches them back to BookingClick → TrialSignup.gclid + click_time are set automatically. Your existing Zapier offline-upload flows have everything they need (Google Ads API requires both gclid + click_time).
Decision: we capture, then hand off. We do NOT create PushPress accounts via Zapier.
Earlier draft of this plan had a "Zap A — Website Lead → PushPress Person" step. We removed it.
Why
How it works now
createTrialLead writes the row, fires GA4 generate_lead, fires Klaviyo (via your existing PushPress→Klaviyo Zap when they complete PushPress, or directly if you want belt-and-braces).?first_name=...&last_name=...&email=...&phone=... pre-filled.linkTrialAttribution Zap fires when PushPress notifies "new person / trial started" → flips in_pushpress + registered_for_trial on the matching TrialLead (matched by email).What this kills
ZAPIER_LEAD_WEBHOOK_URL secret is no longer used. Safe to ignore or delete.Quick map of your existing 5 flows and what changes:
| Existing flow | Triggered when… | Action |
|---|---|---|
| Flow 1 — Free Trial Welcome | Profile registers for free trial in PushPress (now: `plan` set) | Keep as-is — fires when they finish PushPress |
| Flow 2 — Post-Class Convert | Class Attended metric | Keep as-is |
| Flow 3 — New Member Onboarding | `plan` becomes paid Member plan | Keep as-is |
| Flow 4 — Win-Back Lapsed | `status` ≠ active | Keep as-is |
| Flow 5 — 30-day No-Show Campaign | Quarterly segment send | Keep as-is |
| + NEW: Popup Lead Rescue | Profile created from popup (Klaviyo `plan` still empty) | Add this one |
Why the new flow exists
Flow 1 only fires when someone registers for the free trial in PushPress (the moment `plan` gets set in Klaviyo). The new popup creates a Klaviyo profile before that — so we now have a brief gap (popup submitted → PushPress not yet) that nothing covers.
The Popup Rescue flow only sends to profiles where `plan` is still empty. The second `plan` populates (they finish PushPress), Flow 1 takes over and Rescue stops — no duplicate touches.
Popup Rescue — quick summary (4 touches)
Full HTML + SMS copy is on the Klaviyo Flow Guide page — it's the first flow listed.
How the popup profile reaches Klaviyo
Two options — pick whichever is easier:
How Lead Chase + Klaviyo work together
Klaviyo handles the gentle 4-touch automated nudge. The Lead Chase dashboard surfaces the highest-priority leads for phone calls. A "Call today" lead is also getting Klaviyo emails — that's fine, the call is the conversion. The dashboard call notes are your record; Klaviyo runs in the background.
generate_lead conversion.ZAPIER_LEAD_WEBHOOK_URL secret and any "Catch Hook → Create Person" Zap. Capture-then-Passthrough doesn't use them.Reference (PushPress official docs):