Table of Contents
Add hidden fields to your lead forms if you need campaign information alongside contact details in your CRM. You will also need a way to keep those values as visitors move between pages. The examples below show how to capture, store and submit them.
Why Web Forms Need Hidden Attribution Fields
Google Analytics 4 tracks aggregate session counts, but it cannot legally tell your sales reps which specific marketing touchpoint convinced a specific company to request a demo. Capturing UTM parameters directly into your CRM Contact record connects individual ad clicks to pipeline value, deal size, and closed-won revenue.
Setting Up Custom Properties in HubSpot and Salesforce
Before modifying web forms, create matching custom contact fields in your CRM:
utm_source(Single-line text)utm_medium(Single-line text)utm_campaign(Single-line text)utm_content(Single-line text)utm_term(Single-line text)gclid(Single-line text)
HTML Form Markup for Hidden Parameters
Add hidden inputs inside your HTML <form> element:
<form id="lead-form" action="/submit" method="POST">
<!-- Visible Form Fields -->
<input type="text" name="first_name" placeholder="First Name" required>
<input type="email" name="email" placeholder="Work Email" required>
<!-- Hidden UTM Attribution Fields -->
<input type="hidden" name="utm_source" id="utm_source">
<input type="hidden" name="utm_medium" id="utm_medium">
<input type="hidden" name="utm_campaign" id="utm_campaign">
<input type="hidden" name="utm_term" id="utm_term">
<input type="hidden" name="utm_content" id="utm_content">
<input type="hidden" name="gclid" id="gclid">
<button type="submit">Request Demo</button>
</form>
The JavaScript Autofill Script (Handles Direct & Multi-Page Navigation)
This illustrative function saves a complete latest tagged campaign bundle and fills matching hidden fields. Connect it to your consent manager and form-ready lifecycle. Host-only cookies do not share values across subdomains; adapt that intentionally if needed. The script does not validate submitted values or perform GA4 attribution, so verify fields on the receiving server and inspect a test lead:
// Call from your consent manager only when storage is permitted.
function captureCampaign(allowed) {
if (!allowed || location.protocol !== 'https:') return;
const keys = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'utm_id', 'gclid'];
const url = new URLSearchParams(location.search);
let campaign = null;
try {
const raw = document.cookie.split('; ').find(value => value.startsWith('campaign_context='));
if (raw) campaign = JSON.parse(decodeURIComponent(raw.slice('campaign_context='.length)));
} catch { campaign = null; }
if (url.get('utm_source') || url.get('gclid')) {
// Replace the whole bundle; missing values clear old campaign fields.
campaign = Object.fromEntries(keys.map(key => [key, url.get(key) || '']));
campaign.captured_at = new Date().toISOString();
document.cookie = 'campaign_context=' + encodeURIComponent(JSON.stringify(campaign))
+ '; Max-Age=2592000; Path=/; SameSite=Lax; Secure';
}
function fill() {
if (!campaign) return;
keys.forEach(key => {
document.querySelectorAll('input[type="hidden"][name="' + key + '"]').forEach(input => {
input.value = typeof campaign[key] === 'string' ? campaign[key] : '';
});
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', fill, { once: true });
} else { fill(); }
// For forms inserted later, call captureCampaign again from the form's ready hook.
}
// Example integration: call captureCampaign(true) in your permitted-consent callback.
// When consent is withdrawn, clear campaign_context and the populated hidden fields.
Testing Form Submission & CRM Ingestion
- Open an Incognito browser window.
- Paste your test URL:
https://example.com/?utm_source=qa_test&utm_medium=paid_social&utm_campaign=demo_audit. - Click through to your contact or pricing form page.
- Right-click the form, click Inspect, and verify that the
<input type="hidden">elements contain the expected values in their currentvalueproperties. - Submit a test lead and verify that the contact record inside HubSpot or Salesforce displays the parameters accurately.
For the broader setup, read UTM Operations: How to Build a Reliable Campaign Tracking Workflow. Browse the UTM Operations, Automation & QA guides to choose another troubleshooting task.
References
- Set property values with hidden form fields (HubSpot Knowledge Base)