best-practicesUpdated 2025

URL Encoding Complete Guide: Master UTM Parameter Encoding

Comprehensive guide to URL encoding for UTM parameters. Learn when to encode, which characters need encoding, and how to avoid common mistakes.

10 min readbest-practices

URL encoding is the foundation of reliable UTM tracking.

Encode wrong? Data corrupts. Parameters disappear. Campaigns become unmeasurable.

This is your complete reference for encoding UTM parameters correctly every time.

🚨 Not sure what's breaking your tracking?

Run a free 60-second audit to check all 40+ ways UTM tracking can fail.

Scan Your Campaigns Free

✓ No credit card ✓ See results instantly

What is URL Encoding?

URL encoding (percent-encoding) converts special characters into a format safe for URLs.

Code
Original:  "spring sale & save 20%"
Encoded:   "spring%20sale%20%26%20save%2020%25"

Why?
URLs cannot contain spaces, &, %, or many other characters
Each character converts to %XX format (hexadecimal)

Why UTM Parameters Need Encoding

Code
❌ UNENCODED (breaks tracking):
?utm_campaign=spring sale
              ↑     ↑
        Space breaks parsing

✅ ENCODED (tracks correctly):
?utm_campaign=spring%20sale
              ↑   ↑    ↑
         Encoded as %20

Without encoding:

  • Parameters truncate at first space
  • Special characters break parameter separation
  • GA4 receives corrupted data

Characters That MUST Be Encoded

Reserved Characters (Always Encode in Values)

CharacterPurpose in URLEncoded AsExample
SpaceSeparator%20spring%20sale
&Parameter separator%26save%26win
=Key-value separator%3D2%2B2%3D4
?Query string start%3Fwhat%3F
#Fragment identifier%23sale%23promo
%Encoding indicator%2520%25off
+Space alternative%2Bgoogle%2Bads
/Path separator%2Fspring%2Fsale

Unsafe Characters (Always Encode)

CharacterEncoded AsWhy Unsafe
<%3CHTML conflicts
>%3EHTML conflicts
"%22Attribute conflicts
'%27String conflicts
{%7BReserved for future use
}%7DReserved for future use
|%7CReserved
\%5CPath separator
^%5EReserved
[%5BReserved
]%5DReserved
`%60Reserved

Safe Characters (No Encoding Needed)

Code
A-Z a-z 0-9 - _ . ~

These can be used directly in UTM values:
✅ utm_campaign=spring-sale-2024
✅ utm_source=my_email_list
✅ utm_medium=social.paid

😰 Is this your only tracking issue?

This is just 1 of 40+ ways UTM tracking breaks. Most marketing teams have 8-12 critical issues they don't know about.

• 94% of sites have UTM errors

• Average: $8,400/month in wasted ad spend

• Fix time: 15 minutes with our report

✓ Connects directly to GA4 (read-only, secure)

✓ Scans 90 days of data in 2 minutes

✓ Prioritizes issues by revenue impact

✓ Shows exact sessions affected

Get Your Free Audit Report

Encoding Methods

JavaScript: encodeURIComponent()

Javascript
// ✅ RECOMMENDED: For UTM parameter values
const campaign = "spring sale & save 20%";
const encoded = encodeURIComponent(campaign);
console.log(encoded);
// Output: spring%20sale%20%26%20save%2020%25
 
// Build full URL
const url = `https://site.com?utm_campaign=${"{"}{"{"}encoded{"}"}{"}"}}`;

Use encodeURIComponent() for:

  • Individual parameter values
  • Any user-generated content in URLs
  • Campaign names with special characters

JavaScript: URLSearchParams

Javascript
// ✅ AUTOMATIC ENCODING
const params = new URLSearchParams();
params.append('utm_source', 'facebook');
params.append('utm_campaign', 'spring sale');
const url = `https://site.com?${params.toString()}`;
 
console.log(url);
// https://site.com?utm_source=facebook&utm_campaign=spring+sale
 
// Note: URLSearchParams uses + for spaces (valid alternative to %20)

Python: urllib.parse.quote()

Python
from urllib.parse import quote
 
campaign = "spring sale & save 20%"
encoded = quote(campaign)
print(encoded)
# Output: spring%20sale%20%26%20save%2020%25
 
# Build URL
url = f"https://site.com?utm_campaign=`{"{"}{"{"}encoded{"}"}{"}"}}`"

PHP: urlencode()

Php
$campaign = "spring sale & save 20%";
$encoded = urlencode($campaign);
echo $encoded;
// Output: spring+sale+%26+save+20%25
 
// Or use rawurlencode() for %20 instead of +
$encoded = rawurlencode($campaign);
// Output: spring%20sale%20%26%20save%2020%25

Common Encoding Mistakes

Mistake 1: Not Encoding at All

Code
❌ WRONG:
?utm_campaign=spring sale 2024

✅ RIGHT:
?utm_campaign=spring%20sale%202024

Impact: Parameter truncates at first space

Mistake 2: Double-Encoding

Code
❌ WRONG:
const url = "site.com?utm_campaign=spring%20sale";
const encoded = encodeURIComponent(url);
// Result: spring%2520sale (% becomes %25)

✅ RIGHT:
const value = "spring sale";
const encoded = encodeURIComponent(value);
const url = `site.com?utm_campaign=${"{"}{"{"}encoded{"}"}{"}"}}`;
// Result: spring%20sale

Mistake 3: Encoding the Entire URL

Code
❌ WRONG:
const url = "site.com?utm_source=email&utm_campaign=sale";
const encoded = encodeURIComponent(url);
// Result: site.com%3Futm_source%3Demail%26utm_campaign%3Dsale
// (? and & are encoded, breaking URL structure)

✅ RIGHT: Encode only the values
const source = encodeURIComponent("email");
const campaign = encodeURIComponent("sale");
const url = `site.com?utm_source=${"{"}{"{"}source{"}"}{"}"}}&utm_campaign=${"{"}{"{"}campaign{"}"}{"}"}}`;

Mistake 4: Partial Encoding

Code
❌ WRONG:
?utm_campaign=spring%20sale & save
              ↑         ↑ ↑
         Encoded    Not encoded

✅ RIGHT:
?utm_campaign=spring%20sale%20%26%20save

Space Encoding: %20 vs +

Both are valid, but have different behaviors:

Code
%20 (Percent-encoded space)
- Works everywhere
- RFC 3986 standard
- Decoded correctly in all contexts

+ (Plus sign as space)
- Valid in query strings only
- Legacy from application/x-www-form-urlencoded
- Can be ambiguous if actual + is needed

Recommendation: Use %20 for consistency and reliability.

Javascript
// URLSearchParams uses + for spaces
new URLSearchParams({utm_campaign: 'spring sale'}).toString()
// Output: utm_campaign=spring+sale
 
// encodeURIComponent uses %20
encodeURIComponent('spring sale')
// Output: spring%20sale
 
// Both are valid, but %20 is more explicit

Encoding in Different Contexts

Html
<!-- ✅ CORRECT: Encode values before inserting in HTML -->
<a href="https://site.com?utm_campaign=spring%20sale">
    Click Here
</a>
 
<!-- ❌ WRONG: Unencoded spaces -->
<a href="https://site.com?utm_campaign=spring sale">
    Click Here
</a>

JavaScript Redirects

Javascript
// ✅ CORRECT
const campaign = "spring sale";
const url = `https://site.com?utm_campaign=${encodeURIComponent(campaign)}`;
window.location.href = url;
 
// ❌ WRONG
window.location.href = "https://site.com?utm_campaign=spring sale";

Email Templates

Html
<!-- ✅ CORRECT: Pre-encode values -->
<a href="https://site.com?utm_source=newsletter&utm_campaign=spring%20sale">
    Shop Now
</a>
 
<!-- Platforms may add click tracking, but won't break properly encoded URLs -->

Social Media Posts

Code
✅ CORRECT:
Post text: Check out our spring sale!
Link: https://site.com?utm_source=twitter&utm_campaign=spring%20sale

Browser auto-encodes when clicked

Decoding URLs

Javascript
// Decoding when you need to read parameter values
const url = "https://site.com?utm_campaign=spring%20sale%20%26%20save";
const params = new URLSearchParams(new URL(url).search);
const campaign = params.get('utm_campaign');
 
console.log(campaign);
// Output: "spring sale & save" (automatically decoded)

Testing URL Encoding

Javascript
function testEncoding(value) {
    console.log('Original:', value);
    console.log('Encoded:', encodeURIComponent(value));
    console.log('URL:', `https://site.com?utm_campaign=${encodeURIComponent(value)}`);
 
    // Test decoding
    const encoded = encodeURIComponent(value);
    const decoded = decodeURIComponent(encoded);
    console.log('Decoded:', decoded);
    console.log('Match:', value === decoded ? '✅' : '❌');
}
 
// Test cases
testEncoding("spring sale");
testEncoding("save & win");
testEncoding("20% off");
testEncoding("question?");
testEncoding("path/to/page");

Validation Checklist

Javascript
function validateUtmEncoding(url) {
    const checks = [];
 
    // Extract query string
    const queryString = url.split('?')[1] || '';
 
    // Check 1: No unencoded spaces
    if (!queryString.includes(' ')) {
        checks.push('✅ No unencoded spaces');
    } else {
        checks.push('❌ Unencoded spaces detected');
    }
 
    // Check 2: No double encoding
    if (!queryString.includes('%25')) {
        checks.push('✅ No double-encoding');
    } else {
        checks.push('⚠️  Possible double-encoding');
    }
 
    // Check 3: Valid percent encoding
    const invalidPercent = queryString.match(/%(?![0-9A-Fa-f]{2})/);
    if (!invalidPercent) {
        checks.push('✅ Valid percent-encoding');
    } else {
        checks.push('❌ Invalid percent-encoding');
    }
 
    return checks;
}
 
// Usage
const url = 'https://site.com?utm_campaign=spring%20sale';
console.log(validateUtmEncoding(url));

✅ Fixed this issue? Great! Now check the other 39...

You just fixed one tracking issue. But are your Google Ads doubling sessions? Is Facebook attribution broken? Are internal links overwriting campaigns?

Connects to GA4 (read-only, OAuth secured)

Scans 90 days of traffic in 2 minutes

Prioritizes by revenue impact

Free forever for monthly audits

Run Complete UTM Audit (Free Forever)

Join 2,847 marketers fixing their tracking daily

FAQ

When should I encode UTM parameters?

Always encode parameter values that contain:

  • Spaces
  • Special characters (&, =, ?, #, %, etc.)
  • Non-ASCII characters

Should I encode the parameter names (utm_source, utm_medium)?

No. Standard parameter names don't need encoding. Only encode the values.

What about Unicode characters?

Yes, encode Unicode:

Javascript
encodeURIComponent('café')
// Output: caf%C3%A9

Can I use online encoders?

Yes, but building encoding into your workflow is better. Use:

  • encodeURIComponent() in JavaScript
  • urllib.parse.quote() in Python
  • urlencode() / rawurlencode() in PHP

Conclusion

URL encoding is essential for UTM tracking reliability.

Core Rules:

  1. Always encode parameter values containing special characters
  2. Use encodeURIComponent() in JavaScript
  3. Never double-encode
  4. Use %20 for spaces (more reliable than +)
  5. Test encoding with actual clicks, not just visual inspection

Master encoding = Perfect tracking.


Technical Reference: URL Encoding Issues Validation Rule

UTM

Get Your Free Audit in 60 Seconds

Connect GA4, run the scan, and see exactly where tracking is leaking budget. No credit card required.

Trusted by growth teams and agencies to keep attribution clean.