You set up a HubSpot form on your WordPress landing page. Ads are running. Leads start coming in. But when you check your submissions, the traffic source fields are empty. No UTM parameters. No click IDs. Every single lead shows up as “direct” traffic, even though you know they clicked a Google ad. If you use embedded form tracking on your site, this problem is almost certainly costing you money right now.
The issue is not your ad platform. It is not your tag manager. It is the embed itself. When you place a third-party form inside an iframe (an inline frame — an HTML element that loads a separate webpage inside your page), the browser treats that form as a completely different website. Your tracking data sits on one side of a wall. The form sits on the other.
This article explains exactly why that wall exists, which form tools are affected, and what you can actually do about it.
What Happens When You Embed a Form in an iFrame
Think of an iframe like a glass wall in the middle of a room. You can see through it. From a visitor’s perspective, the form looks like it belongs on your page. But structurally, everything on the other side of that glass is a separate environment with its own address, its own cookies, and its own rules.
When a visitor arrives on your landing page from a Google ad, the URL contains tracking parameters like gclid, utm_source, and utm_medium. These parameters belong to your domain. They exist in your page’s address bar, in your page’s JavaScript context, and in cookies your site sets.
The iframe form loads from a different domain entirely — forms.hubspot.com, form.typeform.com, or calendly.com. That form cannot reach through the glass to read your URL. It cannot access your cookies. It does not know where your visitor came from. As far as the form is concerned, the visitor appeared out of thin air.
This affects every tool that uses iframe embeds to place forms on external websites. HubSpot, Typeform, Calendly, Jotform, Google Forms, Cognito Forms, and dozens of others all work this way by default. If the form loads inside an <iframe> tag, the tracking data is on the wrong side of the glass.
Three Reasons Your Embedded Form Tracking Breaks
The data loss is not caused by a single issue. Three separate browser security mechanisms combine to block your tracking data from reaching an embedded form. Understanding all three matters because fixing just one still leaves the other two in place.
1. Cross-Origin JavaScript Restrictions
Browsers enforce a rule called the Same-Origin Policy. An “origin” is the combination of protocol, domain, and port — so https://yoursite.com and https://forms.hubspot.com are different origins. The Same-Origin Policy prevents JavaScript on one origin from reading or modifying content on another origin.
This means your page’s JavaScript cannot reach into the iframe to pre-fill hidden fields. It cannot read what the visitor typed into the form. And the form’s JavaScript cannot reach out to read your page’s URL or DOM (Document Object Model — the structured representation of your page that scripts interact with).
This restriction exists for good reason. Without it, any website could embed your bank’s login page in a hidden iframe and read your password as you type. But the same rule that protects your banking credentials also blocks your UTM parameters from reaching an embedded form.
2. Cookie Isolation
Even if JavaScript cannot cross the origin boundary, you might expect cookies to help. If your site stores UTM data in a cookie, could the form read that cookie? No. Cookies set by your domain are first-party cookies (small data files set by the site the visitor is actively browsing). When a browser loads an iframe from forms.hubspot.com, cookies from your domain are not sent with that request. The form platform only receives its own cookies.
Browser vendors have been tightening these restrictions further. Safari’s Intelligent Tracking Prevention (ITP) already blocks third-party cookies entirely. Firefox’s Enhanced Tracking Protection does the same by default. Chrome is moving toward restricting third-party cookies as well, with ongoing changes to its Privacy Sandbox initiative.
The practical result: even tracking approaches that once worked by sharing cookies across origins are becoming unreliable across all major browsers.
3. Referrer Header Loss
When a browser requests a page, it sends a referrer header telling the destination where the visitor came from. You might hope the iframe’s form would at least receive your page’s URL as a referrer so it could extract UTM parameters from it. Two separate mechanisms prevent this.
First, the iframe’s referrer is its own origin. When the visitor interacts with the form and it submits, the form submission’s referrer is the iframe’s own URL — not your page. The form platform’s server sees forms.hubspot.com/embed/123 as the referrer, which tells it nothing about your visitor’s original traffic source.
Second, browsers may further strip referrer information based on their referrer policy. Modern browsers default to strict-origin-when-cross-origin, which reduces the referrer to just the domain (e.g., https://yoursite.com) when making cross-origin requests. The UTM parameters in the full URL path are stripped away before the request is sent.
Warning: These three mechanisms are enforced independently by the browser. Even if you find a workaround for one — say, passing data via URL parameters to the iframe — the other two can still block your tracking data. A reliable fix needs to address the architectural problem, not just one symptom.
What This Costs You
Missing tracking data is not just an analytics inconvenience. It directly affects how you spend money. When form submissions arrive without source attribution, you cannot calculate cost per lead for individual channels. You cannot tell whether your Google Ads campaign or your Facebook campaign produced more leads. You cannot shut off underperforming spend or double down on what works.
Consider a business spending $3,000 per month across Google, Facebook, and LinkedIn ads. If 40% of leads come through an embedded form that loses all tracking data, nearly half the ad budget is effectively unattributable. That is $1,200 per month in spend with no way to measure return. Over a year, you are making $14,400 in allocation decisions blind.
The problem compounds over time. Without attribution data, ad optimization relies on guesswork. Campaigns that look underperforming may actually be your best lead source — you just cannot see the submissions they generated because the iframe ate the data.
Which Form Tools Are Affected
Not every form tool embeds via iframe. Some use JavaScript to render the form directly in your page’s DOM (the page structure your browser builds), which keeps all tracking data accessible. The table below shows the default embed method for popular form tools and whether iframe tracking data loss applies.
| Form Tool | Default Embed Method | Tracking Data Lost? | Non-iFrame Option Available? |
|---|---|---|---|
| HubSpot | JavaScript embed or iframe | Depends on method | Yes — JS API (hbspt.forms.create()) |
| Typeform | iFrame | Yes | Limited — popup/slider modes still use iframe |
| Calendly | iFrame | Yes | No |
| Jotform | iFrame | Yes | Yes — JavaScript embed option |
| Google Forms | iFrame | Yes | No |
| Cognito Forms | JavaScript embed | No | N/A — default is already non-iframe |
| Gravity Forms | Native WordPress | No | N/A — runs on your server |
| Contact Form 7 | Native WordPress | No | N/A — runs on your server |
| WPForms | Native WordPress | No | N/A — runs on your server |
| Fluent Forms | Native WordPress | No | N/A — runs on your server |
Key takeaway: Native WordPress form plugins (Gravity Forms, Contact Form 7, WPForms, Fluent Forms, and others) do not use iframes. They render directly in your page and process submissions on your server. This makes them inherently compatible with server-side tracking solutions. If tracking accuracy matters to your business, using a native form plugin is the most reliable path — not a workaround, but the genuinely best technical solution.
Common Fixes and Why They Break
Before looking at what actually works, it is worth understanding why the most common suggested fixes fall short. Each approach addresses one of the three barriers but leaves the others intact.
URL Parameter Appending
The most popular advice is to append UTM parameters to the iframe’s source URL. You modify the embed code so instead of loading forms.hubspot.com/embed/123, it loads forms.hubspot.com/embed/123?utm_source=google&utm_medium=cpc.
This requires custom JavaScript on your page to read the current URL parameters and rewrite the iframe’s src attribute dynamically. It can work, but it has significant limitations. You need to write and maintain the script. If your URL parameters change format, the script breaks. The approach only passes the parameters you explicitly handle — miss one, and the data is lost. And the form platform must actually read URL parameters from the iframe URL and attach them to the submission, which not all platforms do.
Most critically, this approach is fragile. It depends on your custom JavaScript running before the iframe loads, on the iframe URL format staying stable, and on the form platform preserving URL parameters through to the submission record. Any of those can change without warning.
postMessage API
The browser provides a legitimate cross-origin communication channel called window.postMessage(). Your page can send a message to the iframe, and the iframe can listen for it. In theory, you send the UTM data and the form receives it.
In practice, this requires code running on both sides of the iframe. You control your page, but you do not control the form platform’s code. Unless HubSpot, Typeform, or Calendly specifically implements a postMessage listener that accepts and stores UTM data, this approach does nothing. Most form platforms do not offer this capability.
Cookie Bridging
Some enterprise-grade solutions attempt to bridge cookies between the parent page and the iframe by using a shared first-party subdomain or a server-side proxy. The idea is to make the iframe’s requests appear to come from your domain so first-party cookies are accessible.
This is technically complex, often requiring DNS configuration, a reverse proxy server, and custom integration with each form platform’s API. It is overkill for most small and mid-sized businesses. The setup varies per form tool, breaks when the platform changes its infrastructure, and introduces security considerations around proxying third-party content through your domain.
The Right Fix: Capture Data Before the iFrame Loads
If the iframe is a glass wall that blocks your tracking data, the solution is not to find increasingly elaborate ways to push data through the wall. The solution is to capture the data on your side of the wall before the form even renders.
Here is the concept. When a visitor arrives on your landing page, your server or your page’s JavaScript already has access to everything you need: the full URL with UTM parameters, click IDs like gclid and fbclid, the referrer header, and any first-party cookies you have set. All of this data is available before the iframe loads.
A server-side tracking approach captures and stores this data the moment the page loads. The tracking record exists independently of whatever form the visitor eventually fills out. Even if the form is an iframe that sends its submission to a third-party server and loses every bit of context, your server already has the attribution data tied to that visitor’s session.
The key shift is conceptual: stop trying to make the iframe aware of your tracking data and instead make your server aware of the submission. If the form is native to WordPress, your server processes the submission directly and can attach tracking data at that point. If the form is an iframe, you need a different matching strategy — or a different form.
How TrueConversion Handles This
TrueConversion is a WordPress plugin that captures UTM parameters, click IDs (gclid, fbclid, msclkid, and others), and referrer data when a visitor first lands on your site. It stores this data in a first-party cookie on your domain and then automatically attaches it to form submissions when a visitor completes a form.
This works reliably with native WordPress form plugins — Contact Form 7, WPForms, Gravity Forms, Fluent Forms, Ninja Forms, Formidable Forms, Elementor Pro Forms, Forminator, and Jetpack Forms. TrueConversion hooks into each plugin’s server-side submission process using WordPress PHP hooks. When the form submits, the plugin reads the tracking data from the first-party cookie and attaches it to the entry. No JavaScript injection. No cross-origin issues. The data capture and the form processing happen on the same server.
Here is what TrueConversion cannot do: it cannot attach tracking data to iframe form submissions that process on a third-party server. This is not a product limitation — it is an architectural constraint. PHP hooks only fire on your WordPress server. When a visitor submits a HubSpot iframe form, that submission goes to HubSpot’s servers. Your WordPress server never sees it, so TrueConversion’s hooks never fire. No WordPress plugin can intercept a form submission that never reaches WordPress.
This is why switching to a native WordPress form plugin is not a workaround — it is the genuinely best technical solution for reliable embedded form tracking. Native forms submit to your server, where server-side tools can process them. The entire tracking chain stays on your domain, under your control, with no glass wall in the way. You can learn more about how TrueConversion works with each supported form plugin.
Tip: If you are currently using an iframe form and losing tracking data, the fastest fix is to replace it with a native WordPress form plugin. TrueConversion’s free plan supports all major WordPress form plugins and captures UTM parameters, click IDs, and referrer data automatically.
When You Must Use an iFrame Form
Sometimes switching to a native WordPress form is not an option. Your CRM workflow might depend on HubSpot forms. Your booking system might require Calendly. Your team may have built complex conditional logic in Typeform that would take weeks to rebuild. In these cases, you need to work within the iframe constraint.
Here are the most practical approaches, ranked by reliability.
Option 1: Use HubSpot’s JavaScript API Instead of an iFrame
HubSpot offers two embed methods, and most people use the wrong one. The standard embed code creates an iframe. But the HubSpot JavaScript API renders the form directly in your page’s DOM using hbspt.forms.create(). This is not an iframe. The form elements become part of your page, which means JavaScript on your page can interact with them and server-side tracking can capture submission data.
Here is how to switch. In your HubSpot account, go to Marketing > Forms and select your form. Click “Share” and choose the “Embed code” option. Look for the JavaScript embed rather than the iframe embed. The code looks like this:
<script charset="utf-8" type="text/javascript" src="//js.hsforms.net/forms/embed/v2.js"></script>
<script>
hbspt.forms.create({
region: "na1",
portalId: "YOUR_PORTAL_ID",
formId: "YOUR_FORM_ID"
});
</script>
Paste this into an HTML block on your WordPress page. The form renders natively in your page’s DOM. Your page’s JavaScript can access the form fields, and tracking scripts can read the current URL’s parameters. HubSpot’s own tracking code also works better in this mode because it shares the page context.
To pass UTM data into hidden fields, add the onFormReady callback:
<script>
hbspt.forms.create({
region: "na1",
portalId: "YOUR_PORTAL_ID",
formId: "YOUR_FORM_ID",
onFormReady: function($form) {
var params = new URLSearchParams(window.location.search);
var fields = ['utm_source', 'utm_medium', 'utm_campaign', 'gclid', 'fbclid'];
fields.forEach(function(field) {
var value = params.get(field);
if (value) {
var input = $form.find('input[name="' + field + '"]');
if (input.length) {
input.val(value).trigger('change');
}
}
});
}
});
</script>
This requires that you have created corresponding hidden fields in your HubSpot form (named utm_source, utm_medium, etc.). Create these in the HubSpot form editor by adding hidden fields and naming them to match your UTM parameters.
Option 2: Use Hidden Fields with URL Parameter Passing (Typeform, Jotform)
Both Typeform and Jotform support hidden fields that can be populated via URL parameters. The approach is to append your tracking parameters to the embed URL so the form platform reads them when the iframe loads.
For Typeform, create hidden fields in your form settings (e.g., utm_source, utm_medium, utm_campaign). Then modify your embed URL to include those parameters. You need JavaScript on your parent page to read the current URL’s parameters and dynamically rewrite the Typeform embed URL before the iframe loads.
This works but inherits all the fragility described in the “URL Parameter Appending” section above. It requires ongoing maintenance and only passes the parameters you explicitly configure.
Option 3: Dual Tracking — Capture on Your Page, Match Later
If you cannot avoid an iframe and cannot use hidden fields, the remaining option is to capture tracking data on your page independently and match it to submissions later. Install TrueConversion (or similar server-side tracking) to record every visitor’s traffic source. Use timestamps and email addresses to manually match entries in your WordPress dashboard with submissions in your form platform.
This is not automated. It requires manual matching or a custom integration between your WordPress database and your form platform’s API. But it preserves the tracking data rather than losing it entirely, and it gives you a foundation to build automation on later.
Warning: URL parameter appending and hidden field approaches are inherently fragile. They depend on the form platform’s URL handling, which can change without notice. Always test your tracking after platform updates, and consider migrating to a native form as a longer-term investment in data reliability.
Choosing the Right Approach for Your Situation
The decision tree is straightforward. Ask yourself two questions.
First: can you replace the iframe form with a native WordPress form plugin? If yes, do it. This is not a compromise. Native forms give you better performance (no external resource loading), full control over design, reliable server-side tracking, and no dependency on a third-party platform’s embed behavior. Plugins like WPForms, Gravity Forms, and Fluent Forms can replicate most form logic that people build in HubSpot or Typeform.
Second: if you must keep the iframe form, does the platform offer a JavaScript (non-iframe) embed? HubSpot does. Jotform does. Cognito Forms does by default. Use the JavaScript embed and pair it with hidden field population.
If neither option works, you are in the “capture and match” territory. Install server-side tracking to preserve the data, and plan a migration path when time allows.
How Click IDs Complicate iFrame Tracking Further
UTM parameters are only part of the picture. Ad platforms also append click IDs to your URLs — gclid for Google Ads, fbclid for Facebook, msclkid for Microsoft Ads. These are unique identifiers tied to specific ad clicks, and they are essential for offline conversion tracking and automated bid optimization.
Click IDs are even harder to pass through iframes than UTM parameters. They are long, opaque strings that change with every click. You cannot pre-configure them as hidden field defaults. They must be captured dynamically from the landing page URL and forwarded to the form in real time.
If you are running Google Ads and relying on gclid for conversion tracking, losing this value means Google cannot attribute the conversion back to the specific keyword, ad group, or campaign that produced it. Your automated bidding strategies lose signal, and your cost per acquisition climbs. For a deeper look at this specific problem, see our article on why gclid disappears between pages and how to fix it.
Embedded Form Tracking Starts on Your Server
The core lesson is architectural. Iframes create a hard boundary between your page and the form. Browser security rules make this boundary nearly impossible to bypass cleanly from the client side. The tools that reliably solve embedded form tracking are the ones that capture data server-side, on your domain, before any iframe enters the picture.
If you are currently losing tracking data to iframe forms, start with the simplest change that fits your situation. Switch to a native form plugin if you can. Switch to a JavaScript embed if you cannot. And regardless of which form you use, install server-side tracking so your attribution data is always captured on the page where your visitor actually landed.
TrueConversion’s how it works page walks through the full capture-to-submission flow. The free plan supports all nine major WordPress form plugins with no entry limits on tracking.
Stop Losing Leads to iFrame Tracking Gaps
TrueConversion captures UTM parameters, click IDs, and referrer data the moment a visitor lands on your site — before any iframe has a chance to lose it. Switch to a native WordPress form, install TrueConversion, and see every lead’s traffic source in your dashboard.
Frequently Asked Questions
Can Google Tag Manager pass UTM data into an iframe form?
Google Tag Manager runs JavaScript on your page, which means it is subject to the same cross-origin restrictions as any other script. GTM can read your page’s URL parameters and cookies, but it cannot inject values into an iframe from a different origin. You could use GTM to rewrite the iframe’s src URL with appended parameters (the URL parameter appending approach), but GTM does not bypass the Same-Origin Policy. The iframe form must still be configured to read and store those URL parameters, which depends entirely on the form platform.
Do any iframe form tools preserve UTM data automatically?
A few form platforms read URL parameters from their iframe embed URL and store them in hidden fields automatically if configured. HubSpot can do this if you set up the tracking URL parameters in your form settings. Typeform supports it through hidden fields and URL parameter mapping. But none of these approaches are automatic out of the box — they all require explicit configuration, and they only capture the specific parameters you set up. Most platforms default to capturing nothing.
Is the iframe tracking problem worse on mobile browsers?
Yes, in practice. Mobile Safari on iOS uses the strictest cookie and tracking restrictions of any major browser, thanks to Apple’s Intelligent Tracking Prevention. Mobile browsers are also more likely to strip referrer headers aggressively. Additionally, mobile users are more likely to switch between apps (e.g., clicking an ad in the Facebook app that opens in an in-app browser), which can create additional context-switching issues that lose tracking parameters before the visitor even reaches your landing page.
If I switch from a HubSpot iframe form to a WordPress form, will my HubSpot CRM still get the leads?
Yes, but you need to set up a connection. Most WordPress form plugins offer HubSpot integration add-ons or you can use a tool like Zapier to send submissions from your WordPress form to HubSpot CRM. WPForms, Gravity Forms, and Fluent Forms all have HubSpot integration options. The lead still reaches HubSpot, but the form submission processes on your WordPress server first — which is exactly what allows server-side tracking tools like TrueConversion to attach the traffic source data before the lead is sent to your CRM.
Leave a Reply