The first time I ran a proper launch — a WP Adminify release, mailing list plus a few partner posts plus a Product Hunt push — I did the tagging by hand in a spreadsheet at 1am. Two weeks later I opened the analytics report to find out which channel had actually worked, and half the traffic was sitting in a bucket called Unassigned. Not "email", not "referral". Unassigned. The links worked. People bought. I simply could not tell where any of them had come from.
The cause was embarrassingly small. On the newsletter links I had written utm_medium=Email with a capital E. On the partner links I had written utm_medium=partner, which sounds sensible and means nothing to Google Analytics. And on one batch I had pasted the URL after it already carried a ?ref=hn query string, so my ?utm_source= started a second question mark and the whole thing fell apart in a few email clients.
None of those are analytics problems. They are string-assembly problems, and string assembly is exactly the sort of thing you should never do by hand at 1am. That is why I built the UTM Builder into toolz.dev: it puts the parameters together correctly, normalises the values, and — the part I actually care about — tells you which GA4 channel your source/medium pair is going to land in before you send the email.
TL;DR: A UTM-tagged URL is your landing page plus a query string carrying
utm_source,utm_mediumandutm_campaign(with optionalutm_term,utm_contentandutm_id). Source is where the click came from, medium is what kind of marketing it was. GA4 builds its channel reports from the medium, and it only recognises a fixed vocabulary —cpc,organic,social,referral,affiliate,displayand a few more. Anything else, including the very temptingutm_medium=facebook, gets filed under Unassigned. Keep every value lowercase and hyphenated, never tag internal links, and let the UTM Builder assemble the string.
What are UTM parameters?
UTM parameters are ordinary query-string key-value pairs appended to a URL. The name is a fossil: Urchin Tracking Module, from Urchin Software, the analytics company Google bought in 2005 and turned into Google Analytics. The parameters survived every rewrite since, which is why a convention designed for a product that no longer exists is still the lingua franca of campaign tracking in 2026 — and why Matomo, Plausible, Fathom, Adobe Analytics and every email platform read them too.
A tagged URL looks like this:
https://toolz.dev/tools/utm-builder?utm_source=newsletter&utm_medium=email&utm_campaign=july-tool-roundup
Your web server ignores the query string entirely — the page renders exactly as it would without it. The analytics script on the page reads the parameters out of the address bar, stores them against the session, and your reports gain a row telling you that this visit came from the July newsletter.
There are six parameters in common use:
| Parameter | What it answers | Example | Required? |
|---|---|---|---|
utm_source |
Who sent the click | newsletter, producthunt, github |
Yes — GA will not attribute a campaign without it |
utm_medium |
What kind of marketing it was | email, cpc, social, referral |
Effectively yes — no medium means no channel |
utm_campaign |
Which campaign it belongs to | july-tool-roundup, black-friday-2026 |
Effectively yes — otherwise reports show "(not set)" |
utm_term |
The paid keyword | utm builder |
Optional, paid search only |
utm_content |
Which variant or placement | header-cta, footer-link, variant-b |
Optional, useful for A/B tests |
utm_id |
The campaign ID from the ad platform | q3-2026-001 |
Optional, used to join with cost data |
The distinction people get wrong is source versus medium, so it is worth being blunt about it. Source is a proper noun. Medium is a category. facebook is a source. social is the medium it belongs to. newsletter is a source; email is its medium. If you find yourself typing a brand name into utm_medium, you have swapped them.
Why does my campaign show up as Unassigned in GA4?
This is the single most common tagging failure, and it is almost always the medium.
GA4 does not invent channels from your data. It has a fixed set of default channel groups — Direct, Organic Search, Paid Search, Organic Social, Paid Social, Email, Affiliates, Referral, Display, Organic Video, Paid Other and a handful more — and it assigns each session to one by pattern-matching the source and medium against rules Google publishes in its Analytics Help documentation. The rule for Email, for example, matches sessions where the source or medium contains email. The rule for Organic Social matches a set of social mediums such as social, social-network, social-media and sm. Paid Search matches a recognised search source and a medium that looks paid — the cp*/ppc/paid* family.
When nothing matches, the session falls through to Unassigned. It is not an error state you get warned about; it is a quiet bucket that your campaign disappears into.
The classic ways to end up there:
- A brand name in the medium.
utm_medium=facebookmatches no rule. You wantedutm_source=facebook&utm_medium=social. - An invented medium.
utm_medium=partner,utm_medium=blog,utm_medium=newsletter— all reasonable English, all invisible to the channel rules. Usereferral,referral, andemailrespectively. - No medium at all. A URL with only
utm_sourcegives GA a source but nothing to categorise it with. - Capitals.
Emailandemailare different strings, and GA4 is case-sensitive. Some channel rules are written to be case-insensitive and some of your reports will not be, which means your one campaign shows up as two rows with half the numbers each.
The UTM Builder checks the source/medium pair against the same rule shapes and prints the channel it expects — Email, Paid Search, Organic Social, Referral, Affiliates, Display, or a loud red Unassigned. It is a two-second check that catches a mistake you would otherwise only discover after the campaign is over, when the data is already wrong and cannot be backfilled.
How do I build a UTM link correctly?
Mechanically, four decisions and one string.
Step 1: Start from the clean landing page URL
Use the canonical, final URL — the one your site actually serves, with https://, without a redirect in front of it. This matters more than it sounds. If you tag http://example.com/pricing and your server 301s to https://example.com/pricing, most servers and CDNs preserve the query string, but not all redirect rules do, and a rule that rewrites the path with a hard-coded target will silently drop everything after the ?. Redirect chains through link shorteners and email click-trackers add more places for that to happen. Tag the destination, not a stepping stone.
If the URL already has a query string (?plan=pro) or a fragment (#features), keep them. A correct builder appends &utm_source=… rather than a second ?, and leaves the #fragment at the very end where the spec puts it — RFC 3986 defines the order as scheme://authority/path?query#fragment, and a fragment placed before the query is not a fragment, it is a broken URL.
Step 2: Fill in source, medium, campaign
Write them as if a stranger will read the report in six months, because that is what happens. utm_campaign=july-tool-roundup is a name you can decode a year later. utm_campaign=c3 is not.
Step 3: Normalise the values
Lowercase everything. Replace spaces — either with hyphens (july-tool-roundup) or by letting the encoder turn them into %20. Both work; only one is readable in a report. Percent-encoding is not optional here: a literal space in a URL is illegal per RFC 3986, and while browsers will paper over it, email clients and messaging apps that linkify text will happily truncate the link at the space and hand your users a 404.
Step 4: Ship the whole string
Copy the finished URL. Do not hand-edit it afterwards — that is where the second ? gets introduced.
For a launch with a dozen placements, batch mode does all of this in one pass: paste source,medium one per line, keep the campaign name shared across all of them, and export the set as CSV straight into whatever sheet you are using to track the launch.
What conventions should a team agree on?
UTM values are free text, which means the only thing standing between you and thirty variations of the same campaign is a convention everyone follows. Ours is four rules long:
- Lowercase always. No exceptions, no judgement calls.
- Hyphens, not underscores or spaces.
black-friday-2026. - Medium comes from a fixed list.
email,cpc,social,paid-social,organic,referral,affiliate,display,sms,qr. If a new placement does not fit one of these, it almost certainly fitsreferral. - Campaign names carry a date or version.
launch-v3-2026-07, notlaunch. You will run the same campaign again.
The hyphen rule has a second life beyond UTMs: it is the same rule that governs readable URL paths, which is why the Slug Generator and the UTM Builder normalise text the same way. Google treats a hyphen as a word separator and an underscore as a joiner — that is a documented behaviour for URLs, and applying it consistently to campaign names costs nothing.
If you want to be strict about it, write the convention into a shared doc and put the UTM Builder link at the top. Most tagging drift comes from someone building a link by copying an old one and editing it in the address bar.
Where should you never put UTM parameters?
On internal links. This is the rule that most often gets broken with good intentions.
Tagging a link from your own blog post to your own pricing page — utm_source=blog&utm_medium=internal — feels like it will tell you which posts drive pricing views. What it actually does in GA4 is start a new session with a new acquisition source. The visitor who arrived from your newsletter, read a post, and clicked through to pricing is now attributed to... your blog. The newsletter's conversion vanishes. You have overwritten the answer to the question you were trying to ask.
If you want to know which internal links get clicked, that is what event tracking or a link-click report is for. UTMs are for the boundary — the moment someone crosses from somewhere else onto your site.
The other two places to avoid them:
- Organic search results. You do not control those URLs, and if you tag a page and Google indexes the tagged variant, you have created a duplicate.
- Anything you expect to be shared onward. A tagged link posted to a forum gets copied into Slack, into a newsletter, into a tweet, and every one of those visits now claims to be from the original campaign. It is not wrong, exactly, but it inflates one row and starves the others.
Do UTM parameters hurt SEO?
They create URL variants, and URL variants can create duplicate content — but this is a solved problem, and the solution is one line of HTML.
Every page should carry a self-referencing canonical tag pointing at its clean URL:
<link rel="canonical" href="https://toolz.dev/tools/utm-builder" />
With that in place, ?utm_source=newsletter and ?utm_source=x and the bare URL all consolidate into one canonical page. Search engines index the clean version, ranking signals accumulate on one URL rather than fragmenting across twenty, and the tagged variants stay out of the index. Google's own documentation on canonicalisation is explicit that this is what canonicals are for.
Two practical notes. First, verify the canonical is actually there and actually self-referencing — a surprising number of themes emit a canonical pointing at the homepage on every page, which is worse than no canonical at all. You can check what a page is emitting with the Meta Tag Generator as a reference for what a correct head block looks like. Second, do not block UTM parameters in robots.txt. Blocking crawl does not remove URLs from the index; it just prevents Google from seeing the canonical tag that would have resolved the duplication. The Robots.txt Generator is for controlling crawl paths, not for cleaning up query strings.
How do UTMs interact with QR codes and offline placements?
This is where campaign tagging earns its keep, because offline has no referrer at all. A poster, a conference badge, a sticker on a laptop, the last slide of a talk — a person scanning that QR code arrives at your site as pure Direct traffic, indistinguishable from someone typing the URL. Unless you tagged it.
Tag the URL before you generate the code:
https://toolz.dev/tools/utm-builder?utm_source=wordcamp-dhaka&utm_medium=qr&utm_campaign=talk-2026
Then feed that into the QR Code Generator. Two things to watch. Long URLs make dense QR codes — every extra character pushes the symbol to a higher version with more modules, which means it needs to be printed larger or scanned closer. Keep the tagged URL as short as the tagging allows: drop utm_content and utm_term unless you genuinely need them, and keep campaign names terse. And use a high error-correction level for anything that will be printed and might get scuffed, at the cost of a slightly denser symbol.
The same logic applies to any placement where the referrer is lost: PDF documents, email signatures, podcast show notes read aloud, in-app links from native mobile apps.
Comparison: how the six parameters behave
| Parameter | Case-sensitive in GA4 | Affects channel grouping | Safe to omit | Typical mistake |
|---|---|---|---|---|
utm_source |
Yes | Yes (with medium) | No | Using a medium value like social as the source |
utm_medium |
Yes | Yes — this is the one | Technically, but do not | Putting a brand name here |
utm_campaign |
Yes | No | Technically, but do not | Reusing one name across quarters |
utm_term |
Yes | No | Yes | Filling it in for non-paid traffic |
utm_content |
Yes | No | Yes | Using it as a second campaign field |
utm_id |
Yes | No | Yes | Confusing it with utm_campaign |
Common Use Cases
A product launch across many channels
You have a newsletter, three partner blogs, Product Hunt, X, LinkedIn, and a Slack community. Every one of those needs its own source, the right medium, and the same campaign name so they roll up together in the report. That is a spreadsheet job, or it is thirty seconds of batch mode: shared campaign, one line per placement, CSV out. Then you can answer "which channel drove signups" in one query instead of squinting at a referrer report.
Auditing links someone else built
Agencies, partners and affiliates will send you tagged URLs, and they will be wrong. Paste the link into the audit field and the builder decomposes it back into its parameters so you can see what will actually be recorded. Nine times out of ten the medium is a brand name and the whole thing was heading for Unassigned.
Email campaigns
Every link in a broadcast should carry the same source and medium (newsletter / email), the same campaign, and a different utm_content — hero-cta, body-link, footer-unsubscribe-adjacent. That is how you learn where in the email people actually click, which is the only reliable way to improve the next one.
Paid ads
Most ad platforms can inject values automatically — Google Ads has auto-tagging with the gclid parameter, which does its own thing and does not need UTMs. But if you are running ads anywhere without auto-tagging, tag them manually: utm_medium=cpc, the real platform in utm_source, and utm_id set to the campaign ID from the ad account so you can join click data to cost data later.
FAQ
What is a UTM builder?
A UTM builder is a tool that assembles a campaign-tagged URL from a landing page and the UTM parameters you want to track. It handles the mechanical parts you would otherwise get wrong by hand — appending the query string correctly when the URL already has one, percent-encoding values, keeping the fragment at the end — and produces a link you can paste into an email, an ad or a QR code.
Which UTM parameters are required?
utm_source is the only one Google Analytics strictly requires to attribute a campaign, but in practice you want utm_source, utm_medium and utm_campaign on every link. Without a medium, GA4 has nothing to match against its channel rules and the session usually lands in Unassigned. Without a campaign name, your reports group the traffic under "(not set)". utm_term and utm_content are optional refinements.
What is the difference between utm_source and utm_medium?
Source is the specific origin of the click — a named site, publication or list, such as newsletter, github or producthunt. Medium is the marketing channel that origin belongs to, such as email, cpc, social or referral. Source is a proper noun, medium is a category. If you are typing a brand name into the medium field, the two have been swapped.
Are UTM parameters case-sensitive?
Yes. Google Analytics 4 treats Email, email and EMAIL as three distinct values, which splits a single campaign across three rows with a third of the numbers each. Keep every UTM value lowercase and hyphenated as a hard rule. The UTM Builder lowercases values by default and warns you when your input contains capitals.
Why is my UTM traffic showing as Unassigned?
Almost always because utm_medium is missing or holds a value GA4 does not map to a channel. GA4 builds its default channel groups from a fixed vocabulary of mediums — email, organic, cpc, social, referral, affiliate, display and a few more — so utm_medium=facebook or utm_medium=partner matches nothing and falls through to Unassigned. Use utm_source=facebook with utm_medium=social instead.
Should I put UTM parameters on internal links?
No. Tagging a link between two pages of your own site starts a new session and overwrites the original acquisition source, so a visitor who arrived from your newsletter suddenly looks like they came from your own blog. Use UTMs only on links that point at your site from somewhere else, and use event tracking to measure internal clicks.
Do UTM parameters hurt SEO?
They create duplicate URLs for the same page, which is why every tagged page should carry a self-referencing canonical tag pointing at the clean URL. With a correct canonical in place, search engines consolidate the signals and the tagged variants are not indexed separately. Do not block UTM parameters in robots.txt — that stops crawlers seeing the canonical that would have fixed the problem.
Can I build many campaign URLs at once?
Yes. Batch mode takes one placement per line — source, source,medium or source,medium,content — applies the shared campaign values to every row, and produces a tagged URL for each. You can copy the whole set or export it as CSV with the predicted channel included, which is the fastest way to prepare a launch or hand a link sheet to a partner.
Related tools: UTM Builder · Slug Generator · URL Encoder · QR Code Generator · Meta Tag Generator · Robots.txt Generator
Related reading: The Web Developer's Toolkit · Data Privacy and Online Tools
