HubSpot forms don't talk to GA4 out of the box.
They load inside an iframe. GA4 can't see inside iframes. So unless you handle it yourself, submissions aren't tracked.
That means your conversion data is incomplete, and attribution is off.
Here's how to fix it.
Why This Needs a Workaround
GA4 can detect standard form submissions.
HubSpot doesn't use standard forms. It loads them inside an iframe, which is effectively a separate page.
GTM and GA4 can't access what happens inside that iframe.
HubSpot does send a message when a form is submitted.
You just need to catch it, push it into the data layer, and fire a GA4 event from there.
What You Need
- GA4 property (Measurement ID starting with G-)
- Google Tag Manager installed
- A HubSpot form you can test with
- Publish access in GTM
Step 1: Add the HubSpot Listener
Create a Custom HTML tag in GTM.
Paste this:
<script>
// v3 forms (legacy embed)
window.addEventListener("message", function(event) {
if (
event.data.type === 'hsFormCallback' &&
event.data.eventName === 'onFormSubmitted'
) {
window.dataLayer.push({
event: 'hubspot-form-submit',
'hs-form-guid': event.data.id
});
}
});
// v4 forms (new editor)
window.addEventListener(
"hs-form-event:on-submission:success",
function(event) {
var form =
window.HubSpotFormsV4 &&
window.HubSpotFormsV4.getFormFromEvent
? window.HubSpotFormsV4.getFormFromEvent(event)
: null;
var formId = form && form.getFormId
? form.getFormId()
: (event.detail && event.detail.formId
? event.detail.formId
: 'unknown');
window.dataLayer.push({
event: 'hubspot-form-submit',
'hs-form-guid': formId
});
}
);
</script>
Set the trigger to All Pages.
Name it something clear.
Step 2: Create the Trigger
Create a Custom Event trigger.
Event name:
hubspot-form-submit
Set to fire on all custom events.
Step 3: Capture the Form ID (optional, but useful)
Create a Data Layer Variable:
- Name:
hs-form-guid
This lets you distinguish between forms later.
Step 4: Send the Event to GA4
Create a GA4 Event tag.
- Event name:
form_submission(orgenerate_lead) - Measurement ID: your GA4 ID
Add parameter:
form_id→ Data Layer Variable
Trigger it on your custom event.
Step 5: Test It
Use GTM preview.
Submit a form.
You should see:
hubspot-form-submitin the data layer- trigger fires
- GA4 event fires
If nothing appears:
- listener not working (usually v3/v4 issue)
If trigger doesn't fire:
- event name mismatch
Step 6: Register the Parameter in GA4
Go to:
Admin → Custom definitions
Create:
- Name: Form ID
- Scope: Event
- Parameter:
form_id
Without this, GA4 won't show the value.
Step 7: Mark as Key Event
If form submissions matter, mark the event as a key event.
Admin → Events → toggle on
This allows:
- conversion reporting
- attribution
- Google Ads optimisation
HubSpot's Native GA Integration
HubSpot can add GA4 tracking to its own pages.
That only helps if your forms live on HubSpot pages.
If your forms are embedded on your site, it doesn't solve this.
It also gives you less control over events and parameters.
Common Issues
No data layer event
Usually a v3/v4 mismatch or script not firing.
Event fires but nothing in GA4
Check DebugView first. Reports lag.
Multiple forms, no breakdown
You need both:
- data layer variable
- custom dimension
Numbers don't match HubSpot
They won't.
HubSpot = server-side. GA4 = client-side.
Ad blockers, consent, timing all affect GA4.
Use:
- HubSpot for leads
- GA4 for attribution
What This Actually Fixes
Without this, you don't know which channels are driving leads.
You just see traffic.
With it, you can see:
- which campaigns generate submissions
- which pages convert
- which forms actually get used
That's the difference between reporting activity and understanding what's working.