Skip to main content

Tracking & identity

For the snippet itself and how to install it, see Getting Started → Install tracking. This page is the model, how an anonymous pageview becomes a named, paying customer.

The three identifiers

FunnelFizz stitches three IDs together into one profile:

IDSourceLifetime
Visitor ID (_fn_vid cookie)Tracker, on first pageview365 days, per browser
User IDYour code, via funnelfizz('identify', { userId })Permanent
Stripe customer ID (cus_…)Stripe, on checkoutPermanent

The point: a session that started anonymous on mobile gets tied to the desktop purchase three weeks later, automatically.

How the stitch works

Day 1 Anonymous pageview → vid_abc (new cookie)
Day 2 funnelfizz('identify', → links vid_abc ↔ user_789
{ userId: 'user_789' })
Day 3 Stripe checkout → matches email → links user_789 ↔ cus_xyz
Day 30 Same user, new device → vid_new (different cookie)
Logs in → identify → links vid_new ↔ user_789
Both vids now roll up to one profile

Reverse-stitching is intentional, events from before identify get re-attributed to the user once the link is established.

The identify call

The single most important call in your code:

funnelfizz('identify', {
userId: 'user_789', // userId or email — at least one is required
email: '[email protected]', // strongly recommended (drives cross-device merge)
plan: 'pro', // optional custom traits
});

Email is the strongest merge key — when the same email appears on two visitor IDs (e.g. Chrome on desktop + Safari on phone), they merge into one profile. userId is also a merge key but is workspace-scoped and won't merge across devices unless your app sets it consistently.

Where to put it: right after signup, on every page after login (idempotent), and after any auth state change. Don't pass passwords, tokens, or any sensitive data.

We do not guess that two anonymous visitors on different devices are the same person. Without identify, anonymous sessions stay separate. Cross-device guessing without identity signals is how creepy tracking happens.

Cross-subdomain identity

For flat 2-label apex domains (example.com, acme.io, mybiz.dev), the snippet auto-detects the apex and sets _fn_vid at the apexapp.example.com, docs.example.com, etc. all share the same visitor cookie automatically.

For multi-label TLDs (example.co.uk, mysite.com.au) the auto-detect cannot tell where the apex ends, so it stays host-only. Set data-cookie-domain explicitly:

<script
src="https://funnelfizz.com/track.js?t=YOUR_TOKEN"
data-cookie-domain=".example.co.uk"
async
></script>

If you want subdomains tracked separately, opt out of auto-detect with data-cookie-domain="host" — each origin gets its own visitor ID.

Email handoff

Tracked links in FunnelFizz emails carry a signed profile token (?fn_ph=…) so a click from a recipient's inbox stitches their profile to the visitor cookie on the landing page, even on a brand-new device. The script strips the token via history.replaceState so it doesn't leak.

Journey events

Every stage entry and conversion writes one journey event. FunnelFizz dedupes duplicates automatically, so retrying the same stage-entry call is safe.

Profile journey view

On any profile's detail page:

2026-04-01 12:04 pageview / Reddit
2026-04-02 09:22 identify user_789 [email protected]
2026-04-05 14:10 stripe_checkout cus_xyz → Pro $9/mo trial
2026-04-12 22:30 subscription_active paid
2026-05-12 22:30 subscription_canceled churned

The dashboard shows aggregates. The journey is the raw trace.

Privacy

  • No third-party tracking. FunnelFizz never sells data.
  • navigator.doNotTrack is honored, DNT visitors send nothing.
  • Profile tokens in URLs are HMAC-signed server-side.
  • For GDPR/CCPA, defer the snippet until your CMP grants "analytics" consent.

Full policy at funnelfizz.com/privacy.