How do you persist UTM parameters across pages?
To persist UTM parameters across pages, read them from the landing URL when the visitor arrives, save them in the browser with a first-party cookie, localStorage or sessionStorage, then write the saved values into hidden form fields on whichever page the visitor converts. Decide whether a new tagged visit should overwrite the stored values.
- Read the UTMs on every page load.
- Store them if present.
- Choose first touch or last touch.
- Fill hidden fields from storage.
- Respect consent.
The UTMs from the tagged landing page are stored in the browser, the visitor browses, a form on any page is filled from storage, and the submission carries the source.
Choose where to store the values
| Storage | Lasts | Readable by server | Notes |
|---|---|---|---|
sessionStorage | Until the tab closes | No | Loses returning visitors |
localStorage | Until cleared | No | Same origin only |
| First-party cookie | Until expiry you set | Yes | Can span subdomains |
A cookie is the usual choice for lead forms, because buyers often come back days later. Browsers limit some script-set cookies, so check MDN's cookie docs and current browser policies.
The code
const KEYS = ["utm_source","utm_medium","utm_campaign","utm_term","utm_content"];
const p = new URLSearchParams(location.search);
const incoming = Object.fromEntries(KEYS.filter((k) => p.get(k)).map((k) => [k, p.get(k)]));
if (Object.keys(incoming).length) {
document.cookie = "utms=" + encodeURIComponent(JSON.stringify(incoming)) +
"; path=/; max-age=" + 60 * 60 * 24 * 90 + "; SameSite=Lax";
}
const m = document.cookie.match(/(?:^|; )utms=([^;]*)/);
const stored = m ? JSON.parse(decodeURIComponent(m[1])) : {};
KEYS.forEach((k) => document.querySelectorAll(`input[name="${k}"]`)
.forEach((el) => { if (stored[k]) el.value = stored[k]; }));
This is last touch: a new tagged visit replaces the old set.
First touch or last touch?
For first touch, only write the cookie when none exists. For both, store two cookies (utm_first, utm_last) and two sets of hidden fields. Attribution models explained covers when each answer is useful.
Consent
Attribution storage typically sits behind your consent banner. Only write the cookie after consent where your visitors' laws require it, and say what you store in your privacy policy.
Test it
Land on /?utm_source=test, browse three pages, submit a form, check the entry. Then land again with utm_source=test2 and confirm your first- or last-touch rule behaved. The field setup itself is in capturing UTM parameters in hidden fields.
That's the manual approach. To skip it, pre-register for Trakt and every submission arrives with its source attached.
Why hand-rolled persistence breaks (and how Trakt helps)
Single-page apps render forms after the script runs. Subdomains don't share localStorage. Consent changes go unhandled.
How Trakt closes the gap
Trakt stores UTMs and click IDs in a first-party cookie, respects Consent Mode v2, OneTrust and Cookiebot, and adds auto-injected hidden UTM fields to every form. It keeps the first touch, connects visits across devices, and syncs source and revenue into your CRM.
Hand-rolled vs. Trakt, by requirement
| Requirement | Your script | Trakt |
|---|---|---|
| Storage | Cookie you maintain | First-party cookie |
| First and last touch | Two sets of code | Built in |
| Forms rendered late | Extra handling | Auto-injected hidden UTM fields |
| A tagged link in the first place | Same either way | Same either way |
FAQ
How do I keep UTM parameters when a user navigates to another page?
Save them on arrival in a cookie or localStorage, then read them back on the page with the form. Appending UTMs to every internal link also works but is fragile.
Should I store UTMs in a cookie or localStorage?
A cookie if you need it across subdomains or on the server, localStorage if a single origin and client-side only is enough. Both need consent handling.
How long should UTM parameters persist?
Match your sales cycle. A window much longer than the time buyers take to decide credits old campaigns for new decisions.
Does persisting UTMs create first-touch or last-touch attribution?
Either, depending on whether new tagged visits overwrite the stored values. Store both if you want both.
Why are UTMs lost after form submission?
Often because the form page never had them. Our guide to UTM data lost on form submission covers the causes.
Do I need consent to persist UTM parameters?
In many regions, yes, when stored in cookies or local storage for analytics. Gate the script on consent.
What to do first
Land on your site with ?utm_source=test, click two pages deep, and submit your main form. If "test" doesn't arrive, add storage before your next campaign.


