HubSpot Form Event Listener: Track Submissions in GTM
HubSpot forms sit in an iframe, so normal form tracking cannot see them. This listener solves that, and gives you the submitted field values too.

HubSpot forms are rendered inside an iframe. That single fact breaks almost every form tracking method people try first, and it is why this listener exists.
By the end of this post you will be tracking successful HubSpot form submissions in GA4, Google Ads and Meta, and you will know how to use the submitted field values safely.
Why normal form tracking fails on HubSpot
Your page and the HubSpot iframe are different origins. Browsers deliberately stop one from reading the other.
So a GTM Form Submission trigger sees nothing. A click trigger on the submit button sees nothing. The URL never changes, so a page view trigger sees nothing either.
What HubSpot does instead is send a postMessage from the iframe up to your page. The listener below catches that message.
The listener code
This is the HubSpot form event listener from DumbData. Copy it exactly.
The full listener is in the copy block at the bottom of this page, with a copy button. It is reproduced exactly as DumbData publish it, so you can copy it straight from here or from their page.
It adds two separate message listeners, one for each stage of a HubSpot submission.
The two events, and the difference between them
hubspot-form-data
Fires on HubSpot’s onFormSubmit callback, which happens when the form is submitted and before HubSpot has finished processing it.
It carries two things: hs-form-guid, which identifies which form was submitted, and hs-formData, which contains the values the person typed.
hubspot-form-success
Fires on HubSpot’s onFormSubmitted callback, after the submission has actually succeeded and the thank you state is shown.
It carries hs-form-guid only.
Which one should be your conversion?
hubspot-form-success. Always.
The data event fires on submission, which includes submissions that then fail. The success event fires when HubSpot confirms it worked. If you fire a Google Ads conversion on the data event, you will count leads that never arrived.
Use hubspot-form-data only for reading the submitted values.
Installing it in GTM
Create a Custom HTML tag in Google Tag Manager.
Paste the listener exactly as it is, including the script tags.
Trigger it on All Pages, or limit it to the pages with HubSpot forms.
Save and Preview.
The listener attaches to the window, so it needs to be running before someone submits. All Pages is the safe default.
Creating the trigger
Create a new trigger, type Custom Event.
Event name: hubspot-form-success
Leave it on All Custom Events.
Save it as something like CE HubSpot Form Success.
If you want a separate conversion per form, add a condition on the form GUID variable below.
Creating the Data Layer Variables
Two are worth creating:
Data Layer Variable with the name hs-form-guid. Call it DLV HubSpot Form GUID.
Data Layer Variable with the name hs-formData. Call it DLV HubSpot Form Data.
The GUID is the useful one for reporting. You can find which GUID belongs to which form in your HubSpot forms list, and it is worth writing that mapping down somewhere, because a GUID on its own means nothing to anyone reading a report.
Sending it to GA4
Create a GA4 Event tag.
Event name: generate_lead
Add a parameter form_id set to DLV HubSpot Form GUID.
Trigger: CE HubSpot Form Success.
Do not send hs-formData to GA4. It contains what the person typed, which means names and email addresses, and sending that to Google Analytics breaches their terms.
Sending conversions to Google Ads
Create the conversion action in Google Ads and note the ID and label.
Create a Google Ads Conversion Tracking tag in GTM with those values.
Trigger: CE HubSpot Form Success.
Turn on Enhanced Conversions and map the email field.
Enhanced Conversions is where hs-formData earns its place. You can pull the email out of it, and Google hashes it in the browser before it is sent. Setup detail: Enhanced Conversions setup.
Meta, Mixpanel and everything else
Same trigger, different tag.
Meta. A Meta Pixel tag with the Lead event.
Mixpanel or Piwik PRO. Their GTM templates accept the custom event trigger directly.
LinkedIn or Microsoft. Their conversion tags, same trigger.
Using the captured form data properly
hs-formData is an array of the submitted fields. It is genuinely useful, and it is personal data, so treat it accordingly.
Reasonable uses:
Extracting the email for Enhanced Conversions or Meta matching, hashed.
Reading a non personal dropdown value, such as enquiry type or budget band, and sending that as a GA4 parameter.
Deciding conversion value based on what they selected.
Unreasonable uses: sending names, emails, phone numbers or free text comments into an analytics tool. Do not do it.
Testing
Open GTM Preview on a page with the form.
Submit it properly with a real email you can check.
Confirm hubspot-form-data appears first, then hubspot-form-success.
Open the Data Layer tab on the success event and confirm the GUID is there.
Confirm your conversion tag fired once, on the success event only.
Check the submission actually arrived in HubSpot.
Common issues
Nothing fires. The form is probably not the standard HubSpot embed. Some setups use the HubSpot API with a custom front end, which does not postMessage at all.
Only the data event fires. The submission is failing on HubSpot’s side. Check for validation errors or a required field you cannot see.
It fires twice. Two HubSpot forms on the page, or the listener installed twice.
The GUID is undefined. The Data Layer Variable name does not match hs-form-guid exactly, including the hyphens.
Privacy
The data event gives you everything the person typed. That is a responsibility rather than a feature.
Gate both tags behind marketing consent, never put raw personal data into analytics, and hash anything you send to an ad platform for matching.
Final thoughts
HubSpot form tracking has a reputation for being difficult and it is really just one listener and one trigger. The part worth getting right is firing on success rather than on submit.
Credit where it is due: the listener above is maintained by DumbData, and it is worth bookmarking their full listener library for the next tool you need.
Need this built properly?
If your HubSpot leads matter, the conversion should fire on success and nothing else. I set up and repair tracking for ecommerce stores and lead generation businesses, so the numbers in your ad accounts match the money in your bank account.
Have a look at what I do, or book a call and we can go through your setup together.
<script type="text/javascript">
window.addEventListener("message", function(event) {
if(event.data.type === 'hsFormCallback' && event.data.eventName === 'onFormSubmit') {
window.dataLayer.push({
'event': 'hubspot-form-data',
'hs-form-guid': event.data.id,
'hs-formData': event.data.data
});
}
});
window.addEventListener("message", function(event) {
if(event.data.type === 'hsFormCallback' && event.data.eventName === 'onFormSubmitted') {
window.dataLayer.push({
'event': 'hubspot-form-success',
'hs-form-guid': event.data.id
});
}
});
</script>


















