HubSpot Forms + Google Ads Conversion Tracking Setup
I see this setup broken in about 60% of the Google Ads accounts I audit. The issue is almost always the same — people assume HubSpot’s native tracking will automatically send conversions to Google Ads, or they set up the Google Ads tag but miss the Enhanced Conversions piece entirely. Your conversion tracking ends up undercounting by 20-30% because iOS users and cookie-blocked submissions aren’t being captured.
What You’ll Have Working By The End
- HubSpot form submissions firing Google Ads conversion events in GTM
- Enhanced Conversions passing email data for better iOS/cookie-blocked attribution
- Conversion tracking that captures 85-95% of actual form submissions (instead of 60-75%)
- Debug visibility in Google Tag Assistant and Google Ads interface
- Proper deduplication so the same lead doesn’t count multiple times
Prerequisites
- Google Tag Manager container installed on your site
- Google Ads account with conversion action already created (Conversion ID + Label)
- HubSpot forms embedded on your website (either HubSpot CMS or external embed)
- Admin access to GTM and Google Ads
- Form submissions currently working and visible in HubSpot contacts
Step 1: Set Up the HubSpot Form Event Listener
HubSpot forms fire a global message event when submitted. You need to capture this and push it to the data layer for GTM to pick up.
Add this code to your site’s global JavaScript (before the closing </body> tag):
window.addEventListener('message', function(event) {
if (event.data.type === 'hsFormCallback' && event.data.eventName === 'onFormSubmitted') {
// Extract form data
var formData = event.data;
var submissionData = formData.data || {};
// Get email from form submission - HubSpot usually puts it in submissionValues
var email = '';
if (submissionData.submissionValues && submissionData.submissionValues.email) {
email = submissionData.submissionValues.email;
}
// Push to data layer for GTM
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'event': 'hubspot_form_submit',
'form_id': submissionData.formId || '',
'form_title': submissionData.formTitle || '',
'user_email': email,
'page_url': window.location.href
});
}
});
If you’re on HubSpot CMS, you can add this through Settings → Website → Pages → Site Footer HTML.
For non-HubSpot sites with embedded forms, add this code directly to your site or through GTM’s Custom HTML tag (fired on All Pages).
Step 2: Create the GTM Trigger
In Google Tag Manager:
- Go to Triggers → New
- Trigger Type: Custom Event
- Event Name:
hubspot_form_submit - This trigger fires on: All Custom Events
- Name it “HubSpot Form Submit”
Step 3: Set Up Data Layer Variables
Create these variables in GTM (Variables → New → Data Layer Variable):
-
Variable Name: DLV - Form ID
- Data Layer Variable Name: form_id
-
Variable Name: DLV - User Email
- Data Layer Variable Name: user_email
-
Variable Name: DLV - Page URL
- Data Layer Variable Name: page_url
Step 4: Configure Google Ads Conversion Tag
- Tags → New → Google Ads Conversion Tracking
- Conversion ID: Your Google Ads conversion ID (format: 123456789)
- Conversion Label: Your conversion label (format: AbCdEfGhIjKlMnOp)
- Conversion Value: Leave blank or set static value
- Conversion Counting: One (critical for lead tracking)
Enhanced Conversions Configuration:
- Enhanced Conversions: Enabled
- User-provided data: Manual
- Email: {{DLV - User Email}}
- Phone: Leave blank (unless you’re capturing phone in your listener)
Triggering: Select your “HubSpot Form Submit” trigger
Which approach should you use for Enhanced Conversions?
- Manual (recommended): You control exactly what data gets passed
- Automatic: Google tries to detect form fields, but often misses HubSpot’s AJAX submissions
- Google Tag Assistant: Only for testing, not production
Step 5: Testing & Verification
Test in Preview Mode
- GTM Preview Mode: Click Preview in GTM
- Submit a test form on your site
- Check GTM Debug Panel:
- Look for the
hubspot_form_submitevent - Verify your Google Ads Conversion tag fired
- Check that
user_emailvariable populated correctly
- Look for the
Verify in Google Ads
- Google Ads → Goals → Conversions
- Status column: Should show “Recording conversions” within 24 hours
- Recent conversions: Check last 7 days for test submissions
Cross-Check Numbers
Compare these numbers after 48-72 hours:
- HubSpot Forms: Contacts → Form submissions count
- Google Ads: Conversions count for your action
- Acceptable variance: 5-15% (Google Ads should be slightly lower due to attribution windows)
Red flags:
- Google Ads showing 50%+ fewer conversions than HubSpot
- No conversions showing in Google Ads after 48 hours
- Enhanced Conversions match rate under 70%
Step 6: Enhanced Conversions Verification
In Google Ads:
- Tools → Measurement → Conversions
- Click your conversion action
- Enhanced conversions section should show:
- Status: Active
- Match rate: 70-90% is typical
- Modeled conversions: Additional attributed conversions from Enhanced Conversions
Low match rates usually mean:
- Email variable not populating correctly
- Users submitting invalid/test email addresses
- Forms being submitted by bots
Troubleshooting
Problem: GTM Preview shows the trigger firing but no email data in the user_email variable
→ Check your form fields. Some HubSpot forms store email in submissionData.submissionValues while others use submissionData.data. Add console.log(submissionData) to debug the structure.
Problem: Google Ads shows “Not recording conversions” status after 24 hours
→ Your Conversion ID or Label is wrong. Double-check these match exactly what’s in your Google Ads conversion action. No spaces, correct capitalization.
Problem: Conversions firing multiple times for the same form submission → The HubSpot message event is firing repeatedly. Add a deduplication check using form submission ID or timestamp to prevent duplicate pushes.
Problem: Enhanced Conversions match rate under 50%
→ Your email extraction isn’t working properly. HubSpot forms sometimes hash or encode the email data. Try extracting from event.data.data.submissionValues.email instead.
Problem: Forms work on desktop but not mobile
→ Mobile HubSpot forms sometimes use different event structures. Add mobile-specific event listeners for hsFormCallback directly instead of relying on the window message event.
Problem: Conversions showing in GTM debug but not reaching Google Ads → Check your GTM publish status. Also verify your Google Ads account linking in GTM (Admin → Account Linking). The conversion tag needs proper permissions.
What To Do Next
Now that your HubSpot forms are tracking conversions in Google Ads, consider these next steps:
- Set up HubSpot Forms tracking for Meta Ads to capture Facebook/Instagram attribution
- Configure HubSpot Forms to GA4 tracking for complete funnel visibility
- Implement HubSpot Forms LinkedIn Ads tracking for B2B campaigns
- Connect HubSpot Forms data directly to HubSpot CRM for automated lead nurturing
Want me to audit your current tracking setup? I’ll check your HubSpot + Google Ads integration and identify what’s broken. Get a free tracking audit here.
This guide is part of the Google Ads Conversion Tracking — complete setups for tracking any conversion source in Google Ads.