UTM Campaign URL Builder
Build campaign links that survive an anchor, an existing query string and three people tagging in three different cases.
https://swiftplugins.pro/pricing?ref=partner&utm_source=newsletter&utm_medium=email&utm_campaign=spring-sale-2026&utm_content=header-link#plans
Parameters
utm_source newsletter
utm_medium email
utm_campaign spring-sale-2026
utm_content header-link
Kept from the original link
ref unchanged
The link has the anchor #plans, so the parameters go before it.
Appending them after the hash instead is the most common way a campaign
link fails silently: the page still scrolls to the right place and the
analytics never see the campaign at all.
Source and medium are the pair every report groups by, so keep them to a
small fixed vocabulary: newsletter, google, facebook for the source, and
email, cpc, social, referral for the medium. Campaign is the free-text
one.
These values are case sensitive in every analytics tool worth using,
which is why the tool lowercases them. Facebook and facebook arrive as
two separate sources and have to be added up by hand from then on.
Never put UTMs on links inside your own site. The parameters start a new
session and overwrite the original source, so your own navigation takes
the credit for the sale that a newsletter earned.
Output is valid and updates as you type.
Fix the highlighted fields to update the output.
A campaign link is a URL with five parameters on it. Three things go wrong often enough that a builder is worth having, and all three fail quietly.
The anchor. https://example.com/page#pricing with the parameters stuck on the end
becomes #pricing?utm_source=…, which is not a query string: it is part of the
fragment. The page still scrolls to the right place, so nothing looks broken, and
the analytics never see the campaign at all.
The case. utm_source=Facebook and utm_source=facebook are two different sources
in every analytics tool worth using. Three people tagging a campaign in three cases
produces three rows that have to be added up by hand from then on.
The existing query string. Plenty of links already carry parameters, and starting
with ? corrupts them.
How to use
- Paste the landing page URL, anchor and all.
- Fill in source and medium. Those two are what every report groups by.
- Add a campaign name, and content if there are two links to tell apart.
- Copy the link from the first line of the output.
Example
Tagging a pricing page link, with an existing ref parameter and a #plans anchor:
https://swiftplugins.pro/pricing?ref=partner&utm_source=newsletter&utm_medium=email&utm_campaign=spring-sale-2026&utm_content=header-link#plans
Parameters
utm_source newsletter
utm_medium email
utm_campaign spring-sale-2026
utm_content header-link
Kept from the original link
ref unchanged
The ref=partner survived, the campaign parameters went in after it, and #plans
stayed at the end. “Spring Sale 2026” became spring-sale-2026.
Pitfalls
Never tag links inside your own site. The parameters start a new session and overwrite the original source, so your own navigation takes the credit for a sale the newsletter earned. If you want to know which internal link was clicked, that is an event, not a campaign.
Keep source and medium to a short fixed list. Write it down and share it.
newsletter and email-newsletter and Newsletter are three sources and one
channel, and no report will ever put them back together.
Medium is the channel type, not the campaign. email, cpc, social,
referral, affiliate. Putting the campaign name in medium is the most common way
a channel report becomes useless.
Do not tag ad platform links by hand when auto-tagging exists. Google Ads
auto-tagging and its own click identifier carry more than UTMs can, and a manual
utm_source on top of it can override what the platform would have recorded.
UTMs are visible to the person clicking, and they get shared. A link tagged
utm_campaign=lapsed-customers-discount will end up in a screenshot. Name campaigns
the way you would if a customer read them, because one will.
They only work on the landing URL. A redirect that drops the query string drops the campaign with it. If your links go through a shortener or a redirect rule, test one and check that the parameters survive to the other end.
Compatibility
Arithmetic and string handling in the browser: nothing is uploaded and nothing is stored. The share link carries your field values, which is a convenient way to hand a colleague the exact tagging convention rather than describing it.
The URL is split by hand rather than with the browser’s URL parser. URL
normalises things a campaign link should not have changed: it lowercases the host,
adds a trailing slash to a bare origin and re-encodes parts of the path. A link that
comes back subtly different from the one someone pasted costs more trust than the
saved code is worth.
Values are encoded with encodeURIComponent, so a kept space becomes %20 rather
than +. Both work in every analytics tool; %20 is the one that survives being
pasted into a document and back out again.
These parameters are a convention rather than a standard, and the tools that read them are Google Analytics, Matomo, Plausible, Fathom and most email platforms. The same five names work in all of them.