How to Persist UTM Parameters Across Your Website and Pass Them into Gravity Forms
Table of Content
When a user lands on your website from Google Ads, social media, email campaigns or any paid channel, UTM parameters carry critical attribution data.
The problem is this.
Most websites only capture UTM values on the first page load. The moment a user clicks to another page, those parameters disappear. When the user finally submits a form, the attribution is lost.
If you are running paid media, that is not just inconvenient. It is expensive.
In this article, we will walk through a clean and scalable way to persist UTM parameters across the entire browsing session and automatically pass them into Gravity Forms.
This is the method we implement for clients at Defyn to ensure accurate attribution, cleaner reporting and better decision making.
Why UTM Persistence Matters
UTM parameters such as:
utm_source
utm_medium
utm_campaign
utm_term
utm_content
allow you to understand exactly where a lead came from.
Without persistence:
• A user lands on Page A with UTMs
• Clicks to Page B
• Submits a form on Page C
• The UTMs are gone
• Your CRM shows “Direct traffic”
Now your reporting is misleading.
Proper persistence ensures:
• Accurate campaign ROI tracking
• Better CRM data
• Clean GA4 conversion attribution
• Smarter marketing investment decisions
The Correct Technical Approach
There are three parts to solving this properly:
- Capture UTM parameters on first visit
- Store them in the browser
- Inject them into Gravity Forms on submission
We recommend using cookies for persistence because:
• They survive page reloads
• They work across the full domain
• They are accessible server side
• They integrate cleanly with Gravity Forms
Step 1: Capture and Store UTM Parameters
Add the following JavaScript site wide. This captures UTM values and stores them in cookies for 90 days.
<script>
(function() {
const KEYS = ["utm_source","utm_medium","utm_campaign","utm_term","utm_content","gclid","fbclid"]; function getParams() {
const params = new URLSearchParams(window.location.search);
const result = {};
KEYS.forEach(key => {
const value = params.get(key);
if (value) result[key] = value;
});
return result;
} function setCookie(name, value, days) {
const date = new Date();
date.setTime(date.getTime() + (days*24*60*60*1000));
document.cookie = name + "=" + encodeURIComponent(value) +
"; expires=" + date.toUTCString() +
"; path=/; SameSite=Lax";
} function getCookie(name) {
const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
return match ? decodeURIComponent(match[2]) : "";
} const incoming = getParams(); KEYS.forEach(key => {
const existing = getCookie(key);
if (!existing && incoming[key]) {
setCookie(key, incoming[key], 90);
}
});
})();
</script>
What is this?
This script ensures that once a user lands with UTM parameters, they are stored and preserved for future pages.
Step 2: Configure Gravity Forms Hidden Fields
Inside Gravity Forms:
• Add Hidden fields for each UTM parameter
• Enable “Allow field to be populated dynamically”
• Set the Parameter Name to match exactly
For example:
Field label: UTM Source
Parameter name: utm_source
Repeat for each UTM value.
Step 3: Populate Gravity Forms from Cookies
Now we connect the cookies to Gravity Forms using a WordPress filter.
Add this to your theme’s functions.php file or a code snippets plugin:
add_filter('gform_field_value', function($value, $field, $name) {
$allowed = array(
'utm_source',
'utm_medium',
'utm_campaign',
'utm_term',
'utm_content',
'gclid',
'fbclid'
); if (in_array($name, $allowed, true) && isset($_COOKIE[$name]) && $_COOKIE[$name] !== '') {
return sanitize_text_field(wp_unslash($_COOKIE[$name]));
} return $value;
}, 10, 3);
Now, whenever a Gravity Form loads, it automatically pulls the stored UTM values from cookies and injects them into the hidden fields.
The user never sees it.
Your marketing team gets clean attribution.
Handling AJAX Loaded Forms
If your forms load in modals or via AJAX, ensure:
• The script runs globally
• Cookies are set before form render
• Gravity Forms dynamic population is enabled
In most cases, the PHP filter approach works seamlessly even with AJAX forms.
Privacy and Compliance Considerations
If you are using consent management tools such as CookieYes or similar, consider:
• Whether UTM cookies are categorised as marketing
• If consent is required before storing them
• Your documented cookie retention policy
We typically configure attribution cookies as functional where appropriate, but this depends on your compliance requirements and legal advice.
Additional Enhancements
For more advanced tracking, you can also capture:
• First touch versus last touch UTMs
• Landing page URL
• Referrer URL
• Timestamp of first visit
• Session ID
This becomes extremely powerful when syncing into:
• HubSpot
• Salesforce
• ActiveCampaign
• Custom CRM integrations
Common Mistakes We See
Only reading UTMs from query strings without persistence
Relying purely on GA4 for attribution while CRM data remains incomplete
Not storing gclid which breaks Google Ads conversion visibility
Forgetting multi domain or subdomain handling
Using JavaScript only solutions that fail on server side validation
Why This Matters for Business Owners
If you are investing in:
Google Ads
Meta Ads
LinkedIn campaigns
Email marketing
Then attribution accuracy directly impacts how you allocate budget.
Without persistent UTMs, you are making decisions based on incomplete data.
That is not strategy. That is guesswork.
Final Thoughts
UTM persistence is not complex, but it must be implemented correctly.
At Defyn, we integrate tracking, analytics and CRM attribution into every build because performance data should be reliable from day one.
If you want to improve your lead tracking, campaign attribution or CRM reporting accuracy, our team can help you implement a robust tracking foundation that scales with your business.
Clean data drives confident decisions.
And confident decisions drive growth.
