Table of Contents
- The End-to-End Lifecycle of Attribution Data
- Browser Capture: Cookies vs localStorage vs sessionStorage
- First-Touch vs Last-Touch: Storing Both in Your CRM
- Hidden Form Fields Implementation (Pure JavaScript)
- Syncing Parameters into HubSpot, Salesforce, and Zoho
- Automating Campaign Link Generation with Zapier & APIs
- Frequently Asked Questions
A tracking workflow needs to cover more than link creation. Decide how your team names campaigns, checks URLs, stores campaign data and passes it into forms and the CRM. This guide shows how those steps fit together.
The End-to-End Lifecycle of Attribution Data
A resilient tracking pipeline moves through four sequential stages:
- Link Creation: Build tagged URLs from the agreed naming rules.
- Client-Side Persistence: Capturing incoming query parameters on the landing page and storing them in client cookies or
localStorage. - Form Injection: Dynamically populating hidden form inputs when the visitor converts on a demo or signup form.
- CRM Ingestion & Revenue Attribution: Storing first-touch and last-touch parameters on Contact, Lead, and Deal records in Salesforce, HubSpot, or custom databases.
Browser Capture: Cookies vs localStorage vs sessionStorage
When a prospect lands on example.com/?utm_source=linkedin&utm_campaign=q4_demo, they may browse several pages before submitting a form. If your form needs campaign values in the CRM, capture and persist the relevant values using a tested implementation; otherwise, the form record may not contain that context. GA4 session attribution follows its own collection and processing rules.
| Storage Mechanism | Lifespan | Subdomain Sharing | ITP Resistance | Verdict |
|---|---|---|---|---|
| First-Party Cookie | Requested expiry; browser and consent rules can shorten it | Only when an appropriate Domain attribute is explicitly configured | Conditional tracking-prevention limits apply | Recommended for Subdomain Support |
| localStorage | Persists until removed by the user, browser or application | No (isolated per origin) | Script-writable storage may be removed after seven days without interaction | Recommended for Single-Domain Apps |
| sessionStorage | Dies when tab is closed | No | Full duration of tab | Too fragile for multi-tab browsing |
First-Touch vs Last-Touch: Storing Both in Your CRM
Do not force your organization into an ideological debate between first-touch and last-touch attribution. Store both simultaneously.
- First Touch (Creation Source): Answers "Which campaign introduced this prospect to our brand?" Set these fields once when the contact is created and never overwrite them.
- Last Touch (Conversion Source): Answers "Which campaign prompted this prospect to request a demo or buy today?" Overwrite these fields on every subsequent form conversion.
Hidden Form Fields Implementation (Pure JavaScript)
This illustrative script reads campaign values, requests host-only cookies over HTTPS and fills hidden fields. Invoke capture only when permitted by your consent policy. This stores a complete latest tagged campaign bundle and timestamp, clearing fields absent from a new campaign. Requested storage can still be unavailable or expire. Adapt the form lifecycle for asynchronous forms and test the saved CRM record:
// 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.
Syncing Parameters into HubSpot, Salesforce, and Zoho
Create dedicated custom properties on your CRM Contact and Deal objects:
First Touch Source,First Touch Medium,First Touch CampaignLast Touch Source,Last Touch Medium,Last Touch CampaignGCLID(Google Click Identifier for offline conversion upload)
Map your web form fields directly to these CRM properties. When an opportunity is created, copy these properties from the Contact to the Deal record to empower revenue reporting.
Automating Campaign Link Generation with Zapier & APIs
For organizations running hundreds of campaigns weekly, manual link building creates a bottleneck. Integrate UTMCraft Bulk Generator or automated webhook scripts into your marketing project management tools (Asana, Monday.com, Jira). When a campaign brief reaches "Approved" status, auto-generate tagged links programmatically.
Frequently Asked Questions
How do hidden form fields capture UTM parameters into CRM systems?
When a visitor lands on your site with UTM parameters, a lightweight JavaScript snippet extracts the values from window.location.search and saves them to localStorage or first-party cookies. When the visitor navigates to a demo or contact form, the script injects those stored values into invisible <input type="hidden"> fields, which submit directly to your CRM.
Should a CRM store first-touch or last-touch UTM parameters?
Capture both if your reporting needs them. Keep the first-touch fields unchanged after capture, and define when to update last-touch fields. Test how the forms handle a later visit without campaign tags.
Why use first-party cookies or localStorage instead of sessionStorage for UTMs?
sessionStorage is wiped as soon as the visitor closes their browser tab. In B2B and high-consideration purchases, prospects frequently research across multiple days before submitting a form. First-party cookies or localStorage preserve attribution data across return visits.
How can I QA a high volume of UTM links before launching?
Use the UTMCraft UTM Checker to review URL syntax, selected parameter presence, naming consistency, spaces, and a limited set of source/medium patterns. It does not reproduce all GA4 channel definitions, test live redirects, or guarantee live channel assignment.
Choose a focused guide
Use these guides when you need to investigate a specific part of this topic.
- GA4 Cost Data Import: Setup, UTM Matching and Troubleshooting
Import advertising costs into GA4, match spend to UTM campaigns, prepare a currency-ready CSV and diagnose missing joins with the validation report.
- Bulk UTM Creation Workflow: Generating Hundreds of Tagged Links Without Errors
Create UTM links for several channels in one batch. Use shared campaign names, review the generated URLs and export them for your team.
- First-Touch vs Last-Touch UTM Attribution: Capture Models, Cookies & CRM Sync
Compare first-touch and last-touch UTM tracking. Define when to save and update campaign values in browser storage, forms and your CRM.
- How to Store UTM Parameters in CRM Hidden Fields (Salesforce, HubSpot & Forms)
Complete guide on capturing UTM parameters in hidden form fields and syncing attribution into Salesforce, HubSpot, and Zoho CRM without losing data.
- Duplicate UTM Parameters: How to Find and Fix Them
Spot repeated UTM keys, choose the intended campaign values, and rebuild clean links without losing other query parameters or URL fragments.
- How to Capture UTM Parameters in Form Hidden Fields
Capture UTM parameters in form hidden fields even after visitors browse other pages: a tested JavaScript snippet, GTM setup, and HubSpot, Gravity Forms, Typeform and Tally steps.
References
- Create HubSpot tracking URLs (HubSpot Knowledge Base)
- Web Storage API Specification (WHATWG)