Guide
Pass first-touch UTMs into an HTML form
Someone arrives through a campaign link, looks around, and returns directly a few days later to fill out a form. The URL on that second visit no longer has the campaign parameters. This example keeps the first visit in the browser and adds selected values to the form when it is submitted.
Start with a native form
Give the form an ID so the script can find it. Keep your real action URL and any validation you already use.
<form id="lead-form" action="/lead" method="post">
<label for="email">Email</label>
<input id="email" name="email" type="email" required>
<button type="submit">Send</button>
</form>
Capture, then attach the fields
Put this after the form. The example assumes your consent manager keeps window.cookieConsent current and calls syncConsent() when the decision changes. Replace that connection with your actual consent manager. The tracker does not provide a consent banner.
<script src="https://cdn.jsdelivr.net/gh/jasenf/attribution-tracker.js@v0.1.1/dist/attribution-tracker.js"></script>
<script>
const hasConsent = () =>
window.cookieConsent === true &&
navigator.globalPrivacyControl !== true &&
navigator.doNotTrack !== '1';
let tracker;
function syncConsent() {
if (hasConsent()) {
tracker = new AttributionTracker({ consent: hasConsent });
} else {
tracker?.clear();
tracker = undefined;
}
}
syncConsent();
// Call syncConsent() again from your consent manager's change callback.
const form = document.querySelector('#lead-form');
form.addEventListener('submit', () => {
form.querySelectorAll('[data-attribution-field]').forEach(field => field.remove());
if (!hasConsent() || !tracker) return;
const data = tracker.getAll() || {};
for (const key of ['utm_source', 'utm_medium', 'utm_campaign', 'ref']) {
if (!data[key]) continue;
const field = document.createElement('input');
field.type = 'hidden';
field.name = `attribution_${key}`;
field.value = data[key];
field.dataset.attributionField = '';
form.append(field);
}
});
</script>
The code attaches only the four named values. It does not include the full landing-page URL or referrer, which may contain sensitive query data. Change the allowlist only after checking what your form endpoint needs.
Test the return visit
Open your site with ?utm_source=newsletter&utm_campaign=launch, grant consent, and then visit the same site without those parameters. Submit the form and inspect the request. It should include attribution_utm_source=newsletter and attribution_utm_campaign=launch once each.
If the visitor leaves before granting consent, this browser-only code cannot recover the earlier landing URL. If your form is submitted through JavaScript without a native submit event, add the values to that form's own payload instead. Clearing browser storage also clears the saved first touch.
For a page you can run locally, use the complete form example. The Google Tag Manager recipe covers the same handoff inside GTM.