Home › Tools › UTM Link Builder

UTM Link Builder

Build campaign URLs with correctly encoded utm_source, utm_medium and utm_campaign. Validates GA4's four newer parameters too.

Fill in your destination and campaign fields, get a properly URL-encoded link, and see warnings for the naming mistakes that silently split one campaign into several in your reports.

How to use it

  1. Paste the destination URL — you can include existing query parameters, they are preserved.
  2. Fill in source, medium and campaign. These three are what every analytics platform needs to attribute the visit.
  3. Copy the result. Check the warnings first — inconsistent casing is the most common way reports get split.

The three parameters that actually matter

utm_source identifies where the traffic came from — a specific newsletter, a specific site, a specific ad platform. utm_medium identifies the channel type: email, social, cpc, referral. utm_campaign identifies the specific promotion.

These three are the minimum. Term and content are refinements: term is for paid keywords, content distinguishes variants of the same link when you are testing two buttons or two placements.

Case sensitivity is the most expensive mistake here

Analytics platforms treat utm_source values as case-sensitive strings. 'Newsletter', 'newsletter' and 'NEWSLETTER' are three separate sources in your reports, and they will stay separate forever because there is no reliable way to merge historical data after the fact.

Pick lowercase for everything and stick to it. This tool warns when it sees mixed case, because fixing it after a campaign has run is not possible.

Never put UTM parameters on internal links

A tagged link starts a new session in most analytics configurations. If a visitor arrives from your newsletter and then clicks a tagged internal link, the original source is overwritten and the visit is attributed to your own campaign instead of the newsletter that actually brought them.

Tag only links that point at your site from somewhere else. Internal navigation should always be untagged.

Why encoding matters more than it looks

Spaces, ampersands and non-ASCII characters have to be percent-encoded or they will truncate the parameter or break the URL entirely. A campaign name with an ampersand in it will silently cut everything after that character.

This tool encodes each value properly and preserves any query parameters already present on the destination URL, so a link to a page that already has its own parameters keeps working.

A plus sign is not a space in this builder

Inside a query string a + does mean a space, which is why Google Ads' {keyword} value-track produces values like running+shoes. That convention is easy to copy by hand and get wrong.

This builder percent-encodes everything you type, so a plus you type yourself becomes %2B and arrives in your reports as a literal plus character — running%2Bshoes, not two words. Type real spaces instead. They are encoded to %20, which every analytics platform reads back correctly.

Platform click IDs beat your UTMs, so do not add both

Google Ads appends gclid when auto-tagging is switched on, and Meta appends fbclid. Both land on your URL whether you asked for them or not, and both are what the ad platform reports against. If you hand-tag the same destination link, one click produces two attribution records, and when they disagree there is no way to tell which one is right.

The rule: where auto-tagging exists, use it and do not hand-tag. UTM parameters are for the places nothing tags automatically — newsletters, organic social posts, partner sites, PDFs, QR codes. For the same reason, do not strip gclid or fbclid to make a URL prettier; the platform needs it to reconcile the click.

The four parameters GA4 added, and why you probably do not need them

Alongside the classic five, GA4 reads utm_id, utm_source_platform, utm_creative_format and utm_marketing_tactic. They exist because one source value is not always enough: utm_source=facebook covers both a paid ad and an organic post, and utm_source_platform is what separates the two.

They start paying off at paid-media volume, where you are comparing dozens of creative formats. This builder stays on the five parameters every analytics platform understands, which is where nearly all of the value is for everyone else.

utm_content should have as many values as you have variants

The failure mode is putting something unique per person into it. A recipient ID, a timestamp, a hash of the email address: each one produces its own row, so instead of 'variant A against variant B' you get four thousand rows and no comparison at all.

A working test has between two and five distinct utm_content values. If yours has more than ten, you are not measuring a variant, you are measuring your mailing list. The same applies to utm_term — it should hold the keyword you bid on, not the query the visitor typed.

When you should not tag a link

Internal links, as described above. Beyond that: do not tag links you click while testing. Every QA visit becomes a session carrying your own campaign. If you cannot avoid it, tag them all identically as utm_source=internal-qa so one filter condition removes them, instead of hunting for them later.

Print and QR codes are the case where length is the real constraint. A 60-character URL makes a sparse code that scans easily; the same URL with four parameters on it can pass 140 characters, which raises the module density and needs a physically larger code to scan from the same distance. Still tag it — offline traffic is otherwise invisible — but use short values.

And do not tag a URL you hand to an ad platform as its final destination if that platform rewrites it. Several append their own parameters, and a few reject or mangle a destination that already carries a query string.

Six failures and how to confirm each one

A spike in (direct) traffic while a campaign is running. A tagged internal link reset the session, or the tag was dropped by a redirect. Confirm it: open the landing page report and look at the entry page. If the entry page is your own site and the source is (direct), the attribution was reset after arrival.

One campaign shows as two rows. Casing. Confirm it: sort the source column and look for neighbours that differ only in capitals.

The campaign has clicks but no sessions. An unencoded & cut the URL short. Confirm it: paste the link into a browser and read the address bar — everything from the ampersand onward will be missing.

Your own domain appears as a referral source. Tagged internal links again, or cross-domain measurement that was never configured. Confirm it: filter the referral report to your own hostname.

Source is populated but medium reads (not set). The link is missing utm_medium. Without a medium the session cannot be placed into a channel, and it will not match the rules that classify anything.

The campaign is filed under an 'Unassigned' channel. The medium value is not one the platform recognises. utm_medium=paid_search, with an underscore, is not the same as cpc — a paid campaign tagged that way will not be grouped with the rest of your paid search.

A naming convention that survives a spreadsheet

Lowercase, hyphens, no spaces, no ampersands. Source names the specific origin. Medium comes from a short fixed list you write down once — email, social, cpc, display, referral, affiliate, sms — and resist adding to it casually, because every new medium is a new channel bucket in your reports.

Prefix the campaign with the period and it sorts chronologically for free: 2026q4-spring-launch sits beside the rest of the quarter's work instead of being scattered alphabetically. It is the same principle as picking one canonical URL and sticking to it — in our canonical survey of 55 homepages, one in five shipped no canonical at all, and the sites that disagreed with themselves were the ones paying for it.

What keeps this intact is the list, not the builder. Write the allowed values into a shared sheet and make people copy from it. A tool can validate the shape of a value; it cannot know that last month's campaign was spring-launch and this month's is spring_launch.

Questions

What is the difference between source and medium?

Source is the specific origin — 'spring-newsletter' or 'google'. Medium is the channel type — 'email' or 'cpc'. One medium contains many sources.

Can I use UTM links on social media?

Yes, and you should. Social platforms often strip referrer information, so tagged links are frequently the only way to attribute that traffic correctly.

Should campaign names use spaces?

Avoid them. Use hyphens or underscores consistently. Spaces require encoding and make the values harder to read in reports.

Will this overwrite existing parameters on my URL?

No. Existing query parameters are preserved and the UTM parameters are appended to them.

Do I need to tag my Google Ads or Meta links?

Not if auto-tagging is switched on. Google appends gclid and Meta appends fbclid, and those are what the platform reports against. Hand-tagging the same link creates a second, competing attribution record. Tag the channels nothing tags automatically — email, organic social, partners, PDFs, QR codes.

How many distinct utm_content values should a test have?

Two to five. If it has more than ten you are not measuring a variant — something unique per person, like a recipient ID or a timestamp, has leaked into the value, and every visitor becomes their own row.

Why does my campaign show up as '(direct)' or 'Unassigned'?

'(direct)' after a click usually means a tagged internal link reset the session, or a redirect dropped the parameters. 'Unassigned' means the medium value is not one the platform recognises — paid_search with an underscore is not the same as cpc, and it will not be grouped with your paid search.

Related tools