Guide · Tracking

Cross-Domain Tracking for Funnels, Iframes and Checkouts: Don't Lose a Single Lead

Why leads from Heyflow, Perspective, Typeform, ClickFunnels, Calendly or Digistore24 lose their source, and how to pass the session across domains, iframes and checkouts.

Daniel Kalcher8 min read

The Meta ad is running, the landing page converts, and still your CRM fills up with leads that have no source, checkout sales show up as "direct" and booked calls don't appear in any report. The reason is almost always the same: somewhere along the way the visitor switches domains, and the tracking loses them.

This guide is for performance marketers, agencies and coaches running funnel setups. By the end you'll know why funnel builders, iframes and checkout pages break tracking, which ways there are to hand over the session, and how to connect Heyflow, Perspective, Typeform, ClickFunnels, Calendly, Digistore24 and CopeCart in practice.

Why leads lose their source when switching domains

Almost all website tracking is client-side tracking: a script in the browser reads UTM parameters and click IDs on the first page view and stores them in first-party cookies. That works as long as the visitor stays on the same domain. A typical lead funnel, though, looks like this:

  1. Click on the ad, landing page on your-company.com
  2. Form embedded as an iframe from heyflow.site or typeform.com
  3. Booking through a calendar widget
  4. Purchase on the Digistore24 or CopeCart checkout page

Each of these handovers runs into three technical limits:

  • Cookies are per domain. A cookie from your-company.com can't be read on heyflow.site. To the tracking on the second domain, the visitor is a stranger with no source.
  • An iframe is a separate document. The script on your page can neither read nor fill the fields inside a third-party iframe.
  • Third-party cookies are largely blocked. A script inside the iframe has its own cookie storage for the other domain, and browsers increasingly block it. Safari, for example, has blocked cookies for cross-site resources by default since March 2020 (WebKit).

The result: the lead arrives by webhook, but with no connection to the visit that holds the ad click.

The principle: hand over an identifier

Every cross-domain tracking solution follows the same principle. Because the destination domain can't read the cookies, an identifier is passed along explicitly. Google Analytics 4, for example, does this with the _gl linker parameter, which is appended to links between the configured domains. It requires the same Google tag with the same measurement ID on all domains (Google Analytics Help).

For lead funnels there are four ways to pass on the session:

SituationApproach
Visitor follows a link between your own domainsSession identifier as a URL parameter on the link
Funnel builder allows custom code and forwards all fieldsScript in the funnel, session ID in a hidden field
Form or booking tool without custom code, but with a redirectRedirect to your thank-you page with the email address in the URL
Link into a checkoutSession identifier in the checkout link

Underneath all of this, matching on contact details acts as a safety net: if the session already knows the visitor's email address or phone number, a lead that arrives later finds its session even without a session ID.

Connecting several of your own domains

If the landing page lives on offer.com and the application form on careers-company.com, you need classic cross-domain tracking. In LeadMetrics the setting is called Multi Domain Tracking. When it's on, the script automatically appends the session identifier to links pointing to other domains. The script on the destination domain picks up that session instead of starting a new one.

What matters:

  • The same snippet everywhere: Every domain has to run exactly the same tracking snippet from the same project. Copy it rather than generating it again with different settings.
  • Real links only: The session is passed on <a href> links. Iframe sources, URLs built in JavaScript and form actions are not rewritten.
  • Think about subdomains: If visitors follow links between www. and funnel., the setting is worth turning on there too.

Funnel builders with custom code: Heyflow and Perspective

Funnel builders like Heyflow and Perspective let you add your own code to the funnel and forward all form fields by webhook. That's the most reliable case:

  1. Add the script to the funnel

    Paste the tracking script into the funnel's head code. In Perspective, on every page of the funnel.
  2. Create a hidden field

    Add a hidden field named lm_session_id and set its content to exactly {{LM_SESS}}, with nothing else. The script replaces the placeholder with the current session ID.
  3. Connect the webhook

    Add the LeadMetrics webhook URL in the funnel tool. Every lead arrives with its session ID and is matched exactly to its visit.

If the funnel isn't its own page but an iframe on your landing page, it starts a session of its own unless something else is handed over. The lead does get attributed, but to a visit whose source is your landing page rather than the ad. In that case the session also has to be passed into the iframe URL. It's simpler to link from the ad straight to the funnel. If the tool supports custom domains, the funnel can also run on a subdomain of your website, where it shares cookies with your site.

ClickFunnels and Meetovo also allow custom code, but their webhooks only send a fixed set of fields. A hidden session field won't arrive there. Add the script anyway: it detects the email address in the form, and the lead is matched on contact details.

Tools without custom code: Typeform and Calendly

Typeform forms and Calendly bookings usually run in an iframe where you can't execute your own script. The solution is a redirect after submission to a thank-you page on your domain that runs the tracking script. The tool passes the email address in the URL, for example ?email=. The script reads it, the session now knows the person, and the lead arriving in parallel by webhook or Zapier finds its session.

  • Typeform: Enter the thank-you page under "Redirect on completion" and insert the answer from the email field as a parameter, for example https://your-company.com/thank-you?email={{field:email}}.
  • Calendly: In the event type settings under "Confirmation Page", redirect to an external site and enable "Pass event details to your redirected page". The booking itself reaches LeadMetrics via Zapier.

Two details decide whether it works: phone numbers have to be URL-encoded (%2B1… instead of +1…), otherwise the plus sign is lost. And the thank-you page has to run the same tracking snippet as the landing page.

💡
Personal data in a URL ends up in browser history and server logs. Only use the redirect with the email address where tracking can't run inside the tool itself, and mention it in your privacy policy.

Checkout pages: Digistore24 and CopeCart

For info products and coaching, the funnel often ends in a payment provider's checkout. Here the session is passed through the checkout link. Put the __LM_SESS__ placeholder into the link, and the script replaces it with the session ID before the click:

CheckoutLink parameter
Digistore24?cid=__LM_SESS__
CopeCart?metadata=__LM_SESS__
Stripe Checkout / Payment Link?client_reference_id=__LM_SESS__

The sale then comes back by webhook with that identifier and lands with the ad the buyer came from. Note that only regular links on your page are rewritten. A button that builds its URL in JavaScript won't get a session ID.

Custom widgets and special cases

If you have your own configurator, a custom booking widget or a page where form detection can't see the email field, you can identify the person yourself. A call like lmetrics.attribute({ email, phone }) attaches the email address and phone number to the current session. When the lead arrives later from the CRM or by webhook, it's matched that way.

How to test your setup

  1. Start with test parameters

    Open the landing page with the tracking parameters of a real ad, for example from the ad preview.
  2. Check the field or link

    In the funnel, the hidden field has to contain a long identifier instead of the {{LM_SESS}} placeholder. In the checkout link, __LM_SESS__ has to be replaced.
  3. Submit a test lead with a unique email

    Submit the form with a unique test address. For redirects: do you land on your thank-you page, and is the email address in the URL?
  4. Check the attribution

    The test lead has to show up with channel, campaign and ad. If the source is missing, the handover broke somewhere.

Common mistakes

  • Script only on the landing page: Funnel pages, thank-you pages and second domains need the same snippet.
  • Placeholder with extras: {{LM_SESS}} is only replaced when it's the field's entire content.
  • Different snippets: Two domains run scripts from different projects or with different settings, so the session can't carry over.
  • Redirects without parameters: A redirect or link shortener strips the session identifier.
  • Your own domain as a source: The funnel builder shows up as the referrer and overwrites the ad.

How click parameters arrive cleanly in the first place is covered in the guide on UTMs and click IDs. How to go from a matched lead to revenue per ad is explained in the guide on lead attribution.

How LeadMetrics helps

  • Every handover method built in: {{LM_SESS}} for hidden fields, __LM_SESS__ for checkout links, redirects with ?email=, lmetrics.attribute() and Multi Domain Tracking for your own domains.
  • Form detection: Email and phone number from form fields are transmitted encrypted and stored on the session, including in single-page apps.
  • Robust matching: Leads are matched by session ID, email address or phone number up to 90 days back, and unmatched leads are re-checked every hour.
  • Ready-made connections: Heyflow, Perspective, OnePage, Meetovo, Typeform and ClickFunnels by webhook, Calendly via Zapier, and sales from Digistore24, CopeCart and Stripe. More on the lead tracking page.

Ready for better tracking?

Try LeadMetrics free for 10 days and see which campaigns actually drive revenue.
Try free for 10 days

Frequently asked questions

Because the funnel builder runs on a different domain than your landing page. Cookies only apply to the domain that set them, and a script on your page can't look inside a third-party iframe. Unless the session is handed over actively, the funnel starts a new, unknown visit.

Terms in this guide

All terms

Related articles

More guides

All guides