Funnel analytics (GTM & dataLayer)
The public funnel (renderer) exposes a single window.dataLayer queue and named event values you can use in Google Tag Manager (Custom Event triggers). Preview mode does not load GTM, GA4, Meta Pixel, or push client analytics.
Modes (Funnel Settings)
| Mode | Behavior |
|---|---|
| Off | No analytics scripts on the live funnel. |
| Quick setup | Loads gtag.js and/or Meta Pixel (only what you configure). Enabled funnel events are sent to Google / Facebook normally. The same events are also pushed to window.dataLayer for GTM — you can ignore dataLayer if you only use Pixel or only GA4. |
| Google Tag Manager | Injects the GTM container only; configure GA4/Pixel inside GTM. |
| GTM + direct IDs | Container and direct tags. The app turns off automatic GA4 page_view on the direct gtag config and does not fire Meta PageView from the direct Pixel snippet — assuming you will fire page views (and optionally Pixel) from GTM. If your container does not include a Meta Pixel tag yet, you will not see Meta page views until you add one or switch to Quick setup. |
Email addresses are never pushed to dataLayer. The user_email_collected event only carries non-PII flags (for example whether a name field was present).
Quick setup: GA4 vs Meta (direct tags)
When GA4 is set, every enabled funnel event is also sent to GA4 as a custom event (same name as in the table below). When Meta Pixel is set, only three funnel events map to Meta standard events: Email capture → Lead, Checkout screen → InitiateCheckout, Purchase completed → Purchase. Other events still go to dataLayer (and to GA4 if configured), but not to Meta’s fbq API.
dataLayer contract (v1)
Every push includes:
event— Custom Event name for GTM (snake_case).funnel_id,funnel_slug,session_id— stable for the browser session (same idea as server-side tracking).- UTM parameters when present in the URL (
utm_source,utm_medium, etc.).
Events
event | When |
|---|---|
funnel_started | First time the funnel is shown in this session (per funnel). |
step_viewed | Each step shown (including the first). |
step_completed | Internal continue: landing CTA, quiz answer → next, paywall continue. |
user_email_collected | Successful email capture (no raw email in the payload). |
checkout_presented | Not a purchase. Checkout screen is shown (Stripe Payment Element mounted, or Paddle pay flow ready). Maps to Meta InitiateCheckout in Quick setup. |
purchase_completed | Purchase / conversion on the client after returning from payment: success step URL includes _w2a_purchase=1 (we add it when building the return URL from checkout) and/or Stripe adds redirect_status=succeeded. That parameter is only a signal for analytics — the event name is purchase_completed. Server-side payment confirmation is a separate topic. |
Extra fields may include step_id, step_type, step_index, processor (stripe / paddle), plan_id, has_name, etc.
GTM setup tips
- Create a Custom Event trigger and set the event name to match the table (e.g.
purchase_completed). - Use Data Layer variables to read
funnel_slug,session_id, or UTM fields. - If you use Quick setup or GTM + direct IDs, align Meta standard events with your pixel strategy (the app maps some events to
Lead,InitiateCheckout,Purchase).
Common questions
Checkout vs success — two different things?
Yes. checkout_presented = user reached the pay screen. purchase_completed = user landed on the success step after a redirect that indicates checkout finished (our ?_w2a_purchase=1 marker or Stripe’s redirect_status). The query param is not “the purchase event”; it triggers firing purchase_completed once.
“Both” mode: why no automatic Meta PageView?
To avoid counting the same page twice when GTM might already load the Pixel and send PageView. We skip the Pixel’s automatic PageView only in GTM + direct IDs mode — if you rely on GTM for Pixel, you should have a PageView there. If you don’t, add a Pixel tag in GTM or use Quick setup.
Related
- Funnel settings — IDs, mode, and per-event toggles.
- Publishing & URLs — live vs preview.