URL encoding for UTM tracking links
UTM parameters are the standard for tracking marketing campaigns in Google Analytics and most other analytics platforms. They’re just regular URL query parameters with a specific naming convention — but they often contain text that needs URL encoding, and getting that encoding wrong silently corrupts your analytics data.
This article covers the UTM parameter spec, the encoding rules, and how to build URLs that survive every channel.
The five standard UTM parameters
| Parameter | Required? | Purpose |
|---|---|---|
utm_source | Required | Where the traffic came from (e.g., google, newsletter) |
utm_medium | Required | Channel type (e.g., cpc, email, social) |
utm_campaign | Required | Campaign name (e.g., spring_sale_2026) |
utm_term | Optional | Paid keyword for search campaigns |
utm_content | Optional | Differentiates ad variants (A/B testing) |
When UTM values need encoding
UTM values are query parameter values, so they follow standard URL encoding rules. They need encoding if they contain:
- Spaces (very common in campaign names: "Spring Sale 2026")
- Punctuation that’s reserved in URLs (
&,=,#,?,+) - Non-ASCII characters (international campaigns)
- Quotes or special characters from copy-paste
A canonical example
// Campaign details
source: "newsletter"
medium: "email"
campaign: "Spring Sale 2026"
content: "CTA Button"
// Build the URL
const params = new URLSearchParams({
utm_source: 'newsletter',
utm_medium: 'email',
utm_campaign: 'Spring Sale 2026',
utm_content: 'CTA Button',
});
const url = `https://example.com/products?${params}`;
// Result:
// https://example.com/products?utm_source=newsletter&utm_medium=email
// &utm_campaign=Spring+Sale+2026&utm_content=CTA+Button
Note: URLSearchParams uses + for spaces (form-encoded variant). Google Analytics and most platforms accept both + and %20.
The classic UTM URL bugs
1. Spaces left unencoded
// Wrong — manually built URL with raw space
const url = "https://example.com?utm_campaign=Spring Sale 2026";
// Browser may auto-fix this when typed, but copy-paste through emails/SMS breaks it
// Right
const url = `https://example.com?${new URLSearchParams({
utm_campaign: 'Spring Sale 2026',
}).toString()}`;
2. Embedded ampersands in values
// Wrong — & in campaign name breaks the URL
?utm_campaign=Smith & Sons Spring Sale&utm_source=newsletter
// Server reads: utm_campaign="Smith ", " Sons Spring Sale", utm_source="newsletter"
// Three parameters where you wanted two.
// Right — encode the ampersand as %26
?utm_campaign=Smith%20%26%20Sons%20Spring%20Sale&utm_source=newsletter
3. Mixed case inconsistency
UTM values are case-sensitive in Google Analytics. utm_source=Newsletter and utm_source=newsletter show as separate sources in reports.
Best practice: always lowercase, use underscores instead of spaces:
utm_source=newsletter
utm_medium=email
utm_campaign=spring_sale_2026
utm_content=cta_button
This avoids both the encoding question and the case-sensitivity problem.
4. Hash fragment confusion
// User wants to link to a specific anchor on the page
// Wrong — UTM after the hash isn’t tracked
https://example.com/page#section?utm_source=newsletter
// Right — UTM before the hash
https://example.com/page?utm_source=newsletter#section
Analytics platforms read UTM parameters from the query string (before #), not the fragment.
Channel-specific gotchas
Email clients
Some email clients pre-process URLs (link preview, click-through tracking, URL shortening). The pre-processed URL might re-encode or double-encode your UTM parameters. Test in the actual email client before launching a campaign.
QR codes
Generators handle encoding correctly when given a clean URL. But if you paste a URL with already-encoded values, some generators double-encode. Provide raw URLs to QR generators.
SMS and instant messaging
Some platforms (especially older SMS gateways) strip URL parameters or break long URLs. Test by sending to yourself. Consider a URL shortener if the destination URL is over ~80 characters.
Social media auto-shorteners
Twitter, LinkedIn, and Facebook auto-shorten URLs, replacing the original with their own tracker. The UTM parameters survive the shortening (passed through to the destination), but the visible URL no longer shows them.
Print campaigns
URLs in print ads typically use a redirect (example.com/spring → real URL with UTM). Direct copy of a long UTM URL is hard for readers to type.
Building UTM URLs programmatically
JavaScript helper
function buildUtmUrl(baseUrl, utm) {
const url = new URL(baseUrl);
for (const [k, v] of Object.entries(utm)) {
if (v) url.searchParams.set(`utm_${k}`, v);
}
return url.toString();
}
buildUtmUrl('https://example.com/products', {
source: 'newsletter',
medium: 'email',
campaign: 'spring_sale_2026',
});
// "https://example.com/products?utm_source=newsletter&utm_medium=email&utm_campaign=spring_sale_2026"
Python helper
from urllib.parse import urlparse, urlunparse, parse_qsl, urlencode
def add_utm(url, **utm):
parts = urlparse(url)
query = dict(parse_qsl(parts.query))
for k, v in utm.items():
query[f'utm_{k}'] = v
new_query = urlencode(query)
return urlunparse(parts._replace(query=new_query))
add_utm('https://example.com/products',
source='newsletter',
medium='email',
campaign='spring_sale_2026')
Naming conventions that work
For values, stick to:
- Lowercase — avoid case-sensitivity reports issues
- Underscores for word separators —
spring_sale_2026notspring sale 2026(no encoding needed) orspring+sale+2026(form-encoded but invisibly different) - Hyphens for hierarchy —
spring-salefor “the spring sale campaign type” - Year in the name — campaigns reuse, so 2026 vs 2025 matters
- Short but specific — long URLs get truncated or look unprofessional
Verifying your UTM URLs
Before launching a campaign:
- Click the URL yourself — does it load the right page?
- Check Google Analytics Real-Time → Traffic Sources for the test click
- Verify all 3+ required parameters appear correctly
- Check the Acquisition → Campaigns report tomorrow for the recorded data
If values look mangled (extra % signs, truncation), trace back through your tooling — most often the bug is in the marketing platform that emits the link, not the destination.
Tools
Google’s Campaign URL Builder generates valid UTM URLs with proper encoding. Most CRMs and email platforms have built-in builders. For one-off URLs, paste the components into our URL builder and copy the encoded result.
Found this useful? Try the URL decoder, the URL encoder, or browse all tools.