I’ve tested two ways to keep UTMs alive from landing to signup and checkout:
- only URL params: append UTMs to every link and return URL
- first-party cookie: capture first touch UTMs and inject them into hidden fields and event payloads
Both work, but each breaks in edge cases like cross-domain payment, Safari ITP, and manual sharing. Which approach has been more reliable for you, and what rules do you use to resolve first-touch vs last-click?
I mix both and set clear precedence.
First touch goes in a cookie with a 90-day TTL. Last click lives in the URL.
I record both on key events. Built it in Web2Wave with a small script block.
Cookie for first touch, URL for last click. I store both.
Web2Wave lets me set these rules once and push them across the funnel. Makes attribution changes a same-day job instead of a sprint.
Watch for double encoding on return URLs. I lost utm_content that way once.
Now I log the raw query string for debugging.
Prefer cookie first touch keep last click
Set hierarchy: partner_click_id, last UTM, first UTM, referrer. Log all, attribute by rule.
For cross-domain payment, use the payment provider’s metadata field to carry UTMs. On return, validate against the cookie and keep both for analysis.
Document the policy so teams do not argue later.
Safari ITP killed my 30-day cookie. I switched to server-set first-party with rolling refresh when the user is active.
I attach campaign_id to the subscription at creation and never change it. For reporting I still keep last click for optimization.
We use cookie first. URLs for overrides.
Hidden fields fail if the form gets cached. Worth testing.