UTM tracking: track UTMs from click to conversion | Orwel
Guide Updated October 21, 2026

UTM tracking: how to track UTMs from click to conversion

UTM tracking means tagging inbound links with utm_source, utm_medium and utm_campaign, reading those parameters when the visitor lands, storing them so they survive later sessions, and attaching them to the conversion. Keep a first touch and a last touch, add ad click IDs like gclid, and you can tell which campaign produced each lead.

Orwel is an event analytics SDK for startups, developers and vibe coders that maps feature adoption and conversion funnels, and feeds the results back to AI agents through MCP.

What UTM parameters are

UTM parameters are key and value pairs added to the query string of a link. They do not change the page. They tell your analytics where the visit came from.

https://example.com/pricing?utm_source=newsletter&utm_medium=email&utm_campaign=october_update

That link is a UTM URL. Anyone who clicks it lands on /pricing, and your analytics can credit the visit to the October newsletter.

There are six parameters most tools read:

Parameter Records Example
utm_source Who sent the visit google, meta, newsletter
utm_medium The channel type cpc, paid, email
utm_campaign The campaign name spring_sale
utm_id The campaign ID 120210000000
utm_term The paid keyword event_analytics
utm_content The creative or link hero_button

Google Analytics asks you to always set source, medium and campaign, describes utm_id as the campaign ID, and treats values as case sensitive, so google and Google are two sources (Google Analytics help on URL builders). Use lowercase everywhere.

How to track UTMs end to end

Adding UTMs to links is the easy part. Most broken attribution comes from what happens after the click. To track UTMs properly you need four steps to work.

1. Tag every inbound link

Every link you control that points to your site from outside gets UTMs: ads, social posts, emails, partner pages, your bio links. Use one naming convention and write it down. The UTM builder lowercases values, replaces spaces and warns you about mixed case, which removes most mistakes before they reach a report.

Do not tag links inside your own site. A UTM on an internal link looks like a new campaign visit and overwrites the real source.

2. Read the parameters on landing

When the visitor lands, a script has to read the query string before anything removes it. Two things often get in the way:

  • Redirects. Link shorteners, http to https redirects and login walls can drop the query string. Test the final URL, not the one you pasted.
  • Client side routers. Some single page apps rewrite the URL on load, or use hash routes like /#/pricing?utm_source=..., where the parameters sit after the # and a naive script never sees them.

3. Store them across sessions

A visitor clicks an ad on Monday, leaves, and signs up on Thursday from a bookmark. If UTMs only live in the current URL, Thursday's signup is credited to "direct" and Monday's campaign gets nothing.

So the values need storage. Within a visit, session storage keeps them through page changes and redirects. Across visits, local storage (or a first party cookie) keeps them until the conversion happens. This is also where you decide what to keep when a second tagged visit arrives, which is the first touch versus last touch question.

4. Attach them to the conversion

The point of tracking UTMs is to know which campaign produced a lead or a customer. So the stored values must travel with the conversion event, the signup or the form submission, not just with page views. Then you can count leads, customers and revenue per campaign, and divide spend by them to get cost per lead and customer acquisition cost.

First touch vs last touch attribution

When a person arrives through more than one campaign before converting, you need a rule for who gets the credit.

Model Credits Good for
First touch attribution The campaign that first brought the visitor Judging which channels create new demand
Last touch attribution The most recent tagged visit before converting Judging which channels close

Example: someone first finds you through a LinkedIn post, comes back a week later through a Google search ad, and signs up. First touch credits LinkedIn. Last touch credits Google.

Neither is the truth on its own. Top of funnel channels tend to look weak on last touch, and retargeting tends to look strong. Keeping both lets you see the difference instead of guessing. Store the first touch once and never overwrite it. Overwrite the last touch on every new tagged visit.

Ad click IDs and auto tagging

Ad platforms add their own parameter to each click, called a click ID:

Click ID Platform
gclid, gbraid, wbraid Google Ads
fbclid Meta (Facebook and Instagram)
ttclid TikTok
msclkid Microsoft Advertising
li_fat_id LinkedIn

In Google Ads this is called auto tagging. It adds a gclid to every click and is needed to track conversions and to bring Google Ads cost data into Google Analytics. In GA4, auto tagging takes priority over manual UTMs (Google Ads help on auto tagging). Keep it on.

Click IDs and UTMs do different jobs. A click ID ties a visit to one specific ad click, which the platform can match back to a campaign. UTMs are readable by any tool and work on channels with no click ID at all, like email. Use both. For Google Ads, add UTMs to the tracking template with ValueTrack parameters so the campaign ID is filled in for you (ValueTrack parameters):

utm_source=google&utm_medium=cpc&utm_campaign={campaignid}&utm_id={campaignid}

For Meta Ads, the fbclid proves a visit came from a Meta ad, but Meta has no click level report to match it with a campaign. Put the campaign ID in utm_id with Meta's dynamic URL parameters (Meta help on dynamic URL parameters):

utm_source=meta&utm_medium=paid&utm_campaign={{campaign.name}}&utm_id={{campaign.id}}

utm_id is the safer key in both cases. A campaign name changes when someone renames it, and the link between old visits and new spend breaks. The ID stays the same.

Single page app pitfalls

Single page apps (React, Vue, Svelte, Next.js and similar) break UTM tracking in a few predictable ways:

  • The router strips the query string. If the app redirects / to /home or cleans the URL on load, read the parameters before the router runs, or store them on the very first page view.
  • Hash routing. With /#/landing?utm_source=x, the parameters live inside the hash. Your tracking has to look there too.
  • Route changes are not page loads. Navigating inside the app does not reload the page, so anything that reads UTMs only on load must keep them in storage for later events.
  • Auth redirects. A sign in flow that bounces through another domain and back often loses the original parameters. Store them before the redirect.
  • Server rendering. If UTMs are read on the server, make sure the client still receives them, or the conversion fired in the browser will arrive without a source.

Privacy notes

  • Never put personal data in UTMs. No emails, names, phone numbers or user IDs. URLs are saved in browser history, server logs, referrer headers and third party analytics, and they get shared in screenshots.
  • UTMs describe campaigns, not people. utm_campaign=october_update is fine. utm_content=jane_at_example_com is not.
  • Tell visitors what you store. If you keep attribution in local storage or cookies, say so in your privacy policy and follow the consent rules that apply to you.

How Orwel tracks UTMs

Orwel does steps 2 to 4 for you. The SDK reads UTMs and click IDs from the query string, then from a query inside the hash (for hash routers), then from the referrer. It captures utm_source, utm_medium, utm_campaign, utm_term, utm_content and utm_id, and from SDK 1.7.0 the click IDs gclid, gbraid, wbraid, fbclid, ttclid, msclkid and li_fat_id.

Within a session they live in sessionStorage, so they survive client side navigation and redirects. Across sessions the SDK keeps an attribution object in localStorage with a first touch written once and a last touch overwritten on every new tagged visit. Every conversion carries that object, so you do not read the URL or pass UTMs yourself:

import { orwel } from 'orwel';

orwel.init({ apiKey: 'orwel_pk_...' });

// On form submit: attribution is attached automatically
await orwel.conversion('lead', { email });

The lead source comes from an explicit source on the conversion if you set one, otherwise from the last touch, then the first touch, then the session. With Google Ads connected, the gclid is matched with synced clicks to find the campaign. With Meta Ads connected, the match uses utm_id, with utm_campaign as a fallback. The Campaigns screen then shows cost per lead, cost per qualified lead and spend that produced no qualified leads.

To check a setup, open your site with ?utm_source=test&utm_campaign=check using a development key, submit a conversion and look at the request in Dev mode. A conversion with no UTMs or click IDs gets a missing_attribution warning and the lead counts as direct.

See marketing attribution in Orwel for the product side, the install guides to add the SDK, and the CAC calculator to turn the numbers into acquisition cost.

Why Orwel

One plan

49 USD a month, 2 USD less every paid month down to 35 USD, or 420 USD a year

No caps

Unlimited leads and visitors under fair use

2-minute install

One script or npm package, or ask your coding agent to do it

MCP server

Claude, Cursor or your own agent read real usage before the next prompt

Semantic catalog

257 ready events, so tracking is named the same in every project

Dev mode

A live debugger and development keys that keep tests out of real data

FAQ

What is UTM tracking?

UTM tracking is tagging inbound links with campaign parameters such as utm_source, utm_medium and utm_campaign, then reading them when a visitor lands and attaching them to conversions. It tells you which source, channel and campaign brought each visit, lead and customer.

How do I track UTMs across multiple sessions?

Store the parameters when the visitor first lands, in local storage or a first party cookie, and attach them to the conversion when it happens. Without storage, a visitor who returns later from a bookmark is counted as direct and the campaign loses the credit.

What is the difference between first touch and last touch attribution?

First touch attribution credits the campaign that first brought the visitor. Last touch attribution credits the most recent tagged visit before the conversion. First touch shows which channels create demand, last touch shows which ones close. Keeping both is more useful than picking one.

Do UTMs work with Google Ads auto tagging?

Yes. Auto tagging adds a gclid, and GA4 gives it priority over manual UTMs. Other tools read UTMs, so add them through the tracking template with ValueTrack parameters such as {campaignid}. Keep auto tagging on.

Why do my UTMs disappear in my single page app?

Usually the router or a redirect removes the query string before your tracking reads it, or the app uses hash routing and the parameters sit after the #. Read the parameters on the first page load, look inside the hash, and keep them in storage for later events.

Can I put an email or user ID in a UTM parameter?

No. URLs are saved in logs, browser history, referrers and third party tools, so personal data in a UTM leaks. Use UTMs to describe campaigns only, and identify people through your sign in or form submission instead.

Keep reading

See what users do with what you shipped

Install in 2 minutes. 14-day free trial, one plan with everything.