Why builders break links
Building a UTM link sounds trivial: glue five parameters onto an address. For a clean address like https://www.example.com/page it is, which is why many builders are written as plain string concatenation and never tested beyond that case. Real landing pages already carry query parameters, point to a #section, or were copied with a space on the end.
When a builder mishandles one of those, the result still looks like a URL. It opens. It may even land on the right page. But the analytics script never receives the campaign, and the click you paid for is filed under Direct. The tests below use one fixed set of values – source newsletter, medium email, campaign sale, content buy, term shoes – and vary only the URL. The builder on this site runs these exact cases as automated unit tests.
Test 1 – Query parameters
- Website URL input
https://www.example.com?coupon=50percent- Expected output
https://www.example.com/?coupon=50percent&utm_source=newsletter&utm_medium=email&utm_campaign=sale&utm_content=buy&utm_term=shoes
What goes wrong when a builder fails
The landing page already carries a parameter – a coupon code, a product filter, a language switch. A correct builder recognises the existing “?” and joins the UTM tags with “&”. A naive builder appends a second “?”, producing …?coupon=50percent?utm_source=newsletter…. The coupon value becomes “50percent?utm_source=newsletter”, there is no utm_source at all, and the visit is recorded without a campaign.
Test 2 – Hash fragment
- Website URL input
https://www.example.com?#section- Expected output
https://www.example.com/?utm_source=newsletter&utm_medium=email&utm_campaign=sale&utm_content=buy&utm_term=shoes#section
What goes wrong when a builder fails
Fragments jump to a section of the page and are common on long landing pages, documentation and single-page apps. They must come last. A builder that simply appends text produces …#section?utm_source=newsletter…; everything after “#” stays in the browser and is never sent to the server, so analytics sees no parameters. The empty “?” in the input is deliberate: a good parser drops it cleanly instead of emitting “?&utm_source”.
Test 3 – Combination
- Website URL input
https://www.example.com?coupon=50percent#section- Expected output
https://www.example.com/?coupon=50percent&utm_source=newsletter&utm_medium=email&utm_campaign=sale&utm_content=buy&utm_term=shoes#section
What goes wrong when a builder fails
Both edge cases at once: keep the coupon, add the UTM tags with “&”, and move the fragment back to the end. Every builder that fails Test 2 fails here, and some that pass Tests 1 and 2 separately still stumble because they check for “?” or “#” but not both.
Test 4 – Space
- Website URL input
https://www.example.com- Parameter inputs
utm_source = " newsletter " utm_medium = " email " utm_campaign = " sale " utm_content = " buy " utm_term = " shoes "- Expected output
https://www.example.com/?utm_source=newsletter&utm_medium=email&utm_campaign=sale&utm_content=buy&utm_term=shoes
What goes wrong when a builder fails
Copy a URL from a document or chat and it often arrives with spaces at either end; campaign names typed by colleagues do too. Here the URL and every value are padded with spaces. A correct builder trims them. A careless one encodes them, so the source becomes “%20newsletter%20” – a new, misspelled source that never matches the clean “newsletter” from other links.
Reading the results
Every expected output has a “/” after the host. A bare host like https://www.example.com is normalised to https://www.example.com/ by the URL standard, and browsers do the same internally, so the tester accepts a missing slash as “Pass (equivalent)”. Parameter order does not affect tracking either; the builder simply uses a predictable order so links are easy to scan.
We used these tests to measure four common spreadsheet formulas – see the results on our UTM spreadsheet template page.