URL Parameters Best Practices: Complete Guide 2024
Master URL parameter structure, naming, encoding, and validation. Best practices for bulletproof campaign tracking in GA4.
You're building campaign URLs for 2024. You want them to work perfectly in GA4, never break, and follow industry standards.
This is the complete best practices guide for URL parameters and UTM tracking.
Table of contents
- URL Parameter Structure (RFC 3986)
- The Standard Format
- UTM Parameter Order (Recommended)
- Naming Conventions
- Use Lowercase Everything
- Use Hyphens or Underscores (Not Spaces)
- Keep It Short
- URL Encoding Rules
- When to Encode
- When NOT to Encode
- JavaScript Encoding
- Parameter Order and Structure
- Start with ? (Question Mark)
- Use & (Ampersand) Between Parameters
- Fragment Comes Last
- Length Limits
- GA4 Limit: 420 Characters
- Individual Parameter Limits (Recommended)
- Validation Checklist
- Pre-Launch Validation
- Automated Validation Function
- Common Mistakes to Avoid
- 1. Uppercase in utmmedium
- 2. Using Internal Links with UTMs
- 3. Forgetting URL Encoding
- 4. Inconsistent Naming
- FAQ
- Should I use hyphens or underscores?
- Do I need to encode hyphens and underscores?
- What's the recommended order for UTM parameters?
- Can I add custom parameters alongside UTMs?
- Should I use + or %20 for spaces?
- How do I handle multiple values for one parameter?
- Conclusion
🚨 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
URL Parameter Structure (RFC 3986)
The Standard Format
https://domain.com/path?key1=value1&key2=value2&key3=value3#fragment
↑ ↑ ↑ ↑
? & & #
Rules:
- ONE question mark
?starts query string - Ampersands
&separate parameters - Equal signs
=connect keys to values - Fragment
#comes last (optional)
UTM Parameter Order (Recommended)
?utm_source=`{"{"}{"{"}source{"}"}{"}"}}`&utm_medium=`{"{"}{"{"}medium{"}"}{"}"}}`&utm_campaign=`{"{"}{"{"}campaign{"}"}{"}"}}`&utm_content=`{"{"}{"{"}content{"}"}{"}"}}`&utm_term=`{"{"}{"{"}term{"}"}{"}"}}`
Why this order:
- Source first (most important)
- Medium second (channel)
- Campaign third (specific initiative)
- Content/Term last (optional details)
Naming Conventions
Use Lowercase Everything
✅ CORRECT:
utm_source=facebook
utm_medium=cpc
utm_campaign=spring2024
❌ WRONG:
utm_source=Facebook (breaks channel grouping)
utm_medium=CPC (inconsistent)
utm_campaign=Spring2024 (mixed case)
Why: GA4 channel grouping is case-sensitive. "cpc" ≠ "CPC".
Use Hyphens or Underscores (Not Spaces)
✅ CORRECT:
utm_campaign=spring-sale-2024
utm_campaign=spring_sale_2024
❌ WRONG:
utm_campaign=spring sale 2024 (breaks URL)
utm_campaign=spring%20sale%202024 (hard to read)
Choose one style and be consistent.
Keep It Short
❌ TOO LONG (82 chars):
utm_campaign=2024-Q1-spring-collection-launch-womens-running-shoes-category-special-promotion
✅ BETTER (32 chars):
utm_campaign=2024-Q1-spring-womens
Reasons:
- GA4 has 420-char URL limit
- Shorter URLs are easier to share
- Less error-prone
- Better user experience
😰 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
URL Encoding Rules
When to Encode
Always encode:
- Spaces →
%20 - Ampersands →
%26 - Question marks →
%3F - Hash symbols →
%23 - Percent signs →
%25 - Plus signs →
%2B
Example:
Raw: utm_campaign=50% off sale
Encoded: utm_campaign=50%25%20off%20sale
When NOT to Encode
Don't encode:
- Hyphens
- - Underscores
_ - Periods
. - Alphanumeric characters
Example:
✅ CORRECT (no encoding needed):
utm_campaign=spring-2024_v1.0
❌ OVER-ENCODED:
utm_campaign=spring%2D2024%5Fv1%2E0
JavaScript Encoding
// Use encodeURIComponent for parameter values
const campaign = '50% off sale';
const encoded = encodeURIComponent(campaign);
// Result: "50%25%20off%20sale"
// Full URL building
function buildCampaignUrl(base, source, medium, campaign) {
const params = new URLSearchParams({
utm_source: source,
utm_medium: medium,
utm_campaign: campaign
});
return `${"{"}{"{"}base{"}"}{"}"}}?${params.toString()}`;
}
// Usage
const url = buildCampaignUrl(
'https://shop.com/products',
'facebook',
'cpc',
'50% off sale'
);
// Result: https://shop.com/products?utm_source=facebook&utm_medium=cpc&utm_campaign=50%25+off+saleParameter Order and Structure
Start with ? (Question Mark)
✅ CORRECT:
domain.com/page?utm_source=x
❌ WRONG:
domain.com/page&utm_source=x (missing ?)
domain.com/pageutm_source=x (no separator)
Use & (Ampersand) Between Parameters
✅ CORRECT:
?utm_source=x&utm_medium=y&utm_campaign=z
❌ WRONG:
?utm_source=x?utm_medium=y (double ?)
?utm_source=x,utm_medium=y (comma separator)
Fragment Comes Last
✅ CORRECT:
domain.com/page?utm_source=x&utm_medium=y#section
❌ WRONG:
domain.com/page#section?utm_source=x&utm_medium=y
Length Limits
GA4 Limit: 420 Characters
Total URL length budget:
- Protocol: 8 chars (https://)
- Domain: 20 chars (average)
- Path: 50 chars (average)
- UTM parameters: 150 chars (target)
- Buffer: 192 chars (for variations)
────────────────────────────────────────
TOTAL: 420 chars (GA4 max)
Individual Parameter Limits (Recommended)
utm_source: max 15 chars
utm_medium: max 15 chars
utm_campaign: max 30 chars
utm_content: max 20 chars
utm_term: max 20 chars
Validation Checklist
Pre-Launch Validation
Before launching ANY campaign:
□ URL starts with https://
□ ONE question mark only
□ Parameters separated by &
□ All UTM parameters lowercase
□ No spaces (use hyphens or URL encoding)
□ Total length ≤ 420 characters
□ Fragment (#) comes last if used
□ All special characters URL-encoded
□ Tested in GA4 Real-Time
□ Campaign name follows naming convention
Automated Validation Function
function validateCampaignUrl(url) {
const errors = [];
// Check 1: HTTPS
if (!url.startsWith('https://')) {
errors.push('Use HTTPS for security');
}
// Check 2: One question mark
const qCount = (url.match(/\?/g) || []).length;
if (qCount === 0) {
errors.push('Missing question mark before parameters');
} else if (qCount > 1) {
errors.push(`Multiple question marks found (${"{"}{"{"}qCount{"}"}{"}"}})`);
}
// Check 3: Length
if (url.length > 420) {
errors.push(`URL too long (${url.length} chars, limit 420)`);
}
// Check 4: Fragment position
const qPos = url.indexOf('?');
const hashPos = url.indexOf('#');
if (hashPos > 0 && qPos > 0 && hashPos < qPos) {
errors.push('Fragment (#) must come after query string (?)');
}
// Check 5: Required parameters
if (!url.includes('utm_source=')) {
errors.push('Missing utm_source');
}
if (!url.includes('utm_medium=')) {
errors.push('Missing utm_medium');
}
if (!url.includes('utm_campaign=')) {
errors.push('Missing utm_campaign');
}
// Check 6: Spaces
if (url.includes(' ')) {
errors.push('URL contains unencoded spaces');
}
return {
valid: errors.length === 0,
errors
};
}
// Usage
const result = validateCampaignUrl('https://shop.com/products?utm_source=facebook&utm_medium=cpc&utm_campaign=spring2024');
if (result.valid) {
console.log('✅ URL is valid');
} else {
console.error('❌ Validation errors:', result.errors);
}Common Mistakes to Avoid
1. Uppercase in utm_medium
❌ WRONG:
utm_medium=CPC (won't match GA4 channel grouping)
✅ CORRECT:
utm_medium=cpc
2. Using Internal Links with UTMs
❌ WRONG:
<a href="/products?utm_source=navbar">Products</a>
(Overwrites original traffic source)
✅ CORRECT:
<a href="/products">Products</a>
(No UTMs on internal links)
3. Forgetting URL Encoding
❌ WRONG:
utm_campaign=50% off
✅ CORRECT:
utm_campaign=50%25%20off
4. Inconsistent Naming
❌ WRONG:
Campaign 1: utm_campaign=spring_2024
Campaign 2: utm_campaign=spring-2024
Campaign 3: utm_campaign=Spring2024
✅ CORRECT (consistent):
Campaign 1: utm_campaign=spring-2024-shoes
Campaign 2: utm_campaign=spring-2024-apparel
Campaign 3: utm_campaign=spring-2024-accessories
✅ 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
Join 2,847 marketers fixing their tracking daily
FAQ
Should I use hyphens or underscores?
Both work. Choose one and be consistent. Most teams use hyphens.
Do I need to encode hyphens and underscores?
No. These characters are safe in URLs and don't need encoding.
What's the recommended order for UTM parameters?
source, medium, campaign, content, term. But any order works—GA4 parses by key name, not position.
Can I add custom parameters alongside UTMs?
Yes. Add your own parameters: ?utm_source=x&custom_param=y. Just ensure they don't conflict with UTM names.
Should I use + or %20 for spaces?
Use %20. The + sign is ambiguous (it can mean either space or plus sign).
How do I handle multiple values for one parameter?
Use comma-separated values or create separate campaigns. Don't use multiple parameters with the same key.
Conclusion
URL Parameter Best Practices:
- Structure:
?first,&between parameters,#last - Naming: Lowercase, hyphens/underscores, max 30 chars
- Encoding: Spaces as %20, special chars encoded
- Validation: Check length, syntax, encoding before launch
- Consistency: Document conventions, train team
Follow these standards, and your campaign URLs will work perfectly in GA4 every time.
Technical Reference: Multiple Question Marks Validation Rule