UTM Parameters Complete Guide for Developers 2025
Master UTM parameters for accurate campaign tracking. Learn all 5 UTM params with real examples, naming conventions, GA4 setup, and best practices for developers.
If you’ve ever asked “which marketing channel is actually driving signups?”, UTM parameters are your answer. They’re a simple but powerful mechanism for passing campaign data through URLs into your analytics platform—and as a developer, understanding them will make you a better collaborator with your marketing team and a better builder of data-driven products.
This guide covers everything you need to know: what UTM parameters are, how all five work, naming conventions that scale, GA4 integration, and implementation patterns for common frameworks.
What Are UTM Parameters?
UTM stands for Urchin Tracking Module—named after Urchin Software, which Google acquired in 2005 and turned into Google Analytics.
UTM parameters are query string key-value pairs appended to URLs. When a user clicks a UTM-tagged link, the values are captured by your analytics tool, allowing you to attribute that visit to a specific campaign, source, and medium.
Example of a UTM-tagged URL:
https://devplaybook.cc/tools/utm-campaign-builder?utm_source=newsletter&utm_medium=email&utm_campaign=march-launch&utm_content=cta-button&utm_term=developer+tools
Without UTM parameters, all email clicks might show up as “direct” traffic in GA4. With them, you get granular attribution.
The 5 UTM Parameters Explained
1. utm_source (Required)
What it is: Identifies where the traffic is coming from—the referrer.
Format: Single word or short identifier, lowercase.
utm_source=google
utm_source=newsletter
utm_source=twitter
utm_source=devto
Real examples:
utm_source=google— paid search on Googleutm_source=linkedin— LinkedIn post or adutm_source=partner_devhunt— a specific partner siteutm_source=internal— internal email campaigns
2. utm_medium (Required)
What it is: The marketing channel or medium. Think of it as the type of traffic.
Standard medium values (follow these):
cpc— cost-per-click paid adsemail— email campaignssocial— organic social postsreferral— links from other websitesorganic— organic search (usually set by the search engine itself)banner— display banner adsaffiliate— affiliate links
utm_medium=email
utm_medium=cpc
utm_medium=social
utm_medium=referral
Why standardize? GA4 uses utm_medium to populate the “Default Channel Group” report. Using non-standard values like utm_medium=newsletter instead of utm_medium=email will break channel grouping.
3. utm_campaign (Required)
What it is: The specific campaign name. This ties multiple sources together under one initiative.
utm_campaign=spring-sale-2025
utm_campaign=developer-onboarding
utm_campaign=product-launch-v2
utm_campaign=retargeting-q1
Best practices:
- Use lowercase with hyphens:
utm_campaign=black-friday-2025notBlack Friday 2025 - Include the year/quarter for time-bound campaigns
- Be specific enough to distinguish campaigns, but not so granular that reports become unreadable
4. utm_content (Optional)
What it is: Differentiates links that point to the same URL within the same campaign. Used for A/B testing ad copy, or distinguishing multiple CTAs in one email.
utm_content=cta-top
utm_content=cta-bottom
utm_content=hero-banner
utm_content=sidebar-link
Example: You have two buttons in an email that both point to /pricing. You want to know which gets more clicks:
- Button 1:
utm_content=header-cta - Button 2:
utm_content=footer-cta
5. utm_term (Optional)
What it is: Originally for paid search—captures the keyword that triggered the ad. Now also used to pass custom information in non-search contexts.
utm_term=javascript+tutorial
utm_term=best+devtools
Modern usage: For non-search campaigns, some teams repurpose utm_term to track newsletter segment, influencer handle, or audience targeting bucket.
Naming Convention Best Practices
Poor naming kills UTM reporting. These conventions will save you pain:
Use lowercase, always
GA4 is case-sensitive. utm_source=Twitter and utm_source=twitter create two separate source entries.
# Bad
utm_source=Twitter&utm_medium=Social&utm_campaign=MarchLaunch
# Good
utm_source=twitter&utm_medium=social&utm_campaign=march-launch
Use hyphens, not spaces or underscores
# Bad (spaces become %20, ugly in reports)
utm_campaign=spring sale
# Acceptable (underscores work but inconsistent)
utm_campaign=spring_sale
# Best (hyphens are standard)
utm_campaign=spring-sale
Define a taxonomy and document it
Create a shared spreadsheet or wiki page with approved values for each parameter. Teams that skip this end up with utm_source=Email, utm_source=email, and utm_source=EMAIL all appearing as separate sources.
Suggested taxonomy:
| Parameter | Approved Values |
|---|---|
utm_source | google, facebook, twitter, linkedin, newsletter, devto, github |
utm_medium | cpc, email, social, referral, banner, affiliate, organic |
utm_campaign | [product]-[type]-[year], e.g., devplaybook-launch-2025 |
Include a UTM builder in your workflow
Use a UTM campaign builder to enforce consistency. Many teams integrate this into their CMS or marketing automation platforms so UTMs are generated programmatically.
How UTM Parameters Work with GA4
Viewing UTM data in GA4
- Navigate to Reports → Acquisition → Traffic acquisition
- Set the primary dimension to Session source/medium or Session campaign
- You’ll see your UTM-tagged campaigns broken out
For deeper analysis:
- Explorations → Free form → drag in
Session source,Session medium,Session campaign - Use secondary dimensions to correlate UTM data with conversions
GA4 Default Channel Grouping
GA4 automatically assigns traffic to channel groups based on utm_source and utm_medium values. The rules:
| Channel | Condition |
|---|---|
| Organic Search | utm_medium = organic |
| Paid Search | utm_medium = cpc or ppc |
utm_medium = email | |
| Social | utm_medium in social platforms list |
| Referral | Other sessions with referrer |
Using non-standard medium values (like utm_medium=newsletter) puts traffic into “Unassigned” or a custom group—which breaks default reporting.
How UTM Parameters Work with GTM
Google Tag Manager captures UTM parameters as built-in variables:
- In GTM, go to Variables → Built-In Variables → Configure
- Enable:
Traffic Source,Medium,Campaign
These variables are populated from document.referrer and location.search on the page.
Custom GTM variable for manual UTM reading:
// Custom JavaScript variable in GTM
function() {
var params = new URLSearchParams(window.location.search);
return {
source: params.get('utm_source') || '(none)',
medium: params.get('utm_medium') || '(none)',
campaign: params.get('utm_campaign') || '(none)',
content: params.get('utm_content') || '(none)',
term: params.get('utm_term') || '(none)'
};
}
Developer Implementation Guide
Reading UTM Parameters in JavaScript
function getUTMParams() {
const params = new URLSearchParams(window.location.search);
return {
utm_source: params.get('utm_source'),
utm_medium: params.get('utm_medium'),
utm_campaign: params.get('utm_campaign'),
utm_content: params.get('utm_content'),
utm_term: params.get('utm_term'),
};
}
// Usage
const utm = getUTMParams();
console.log(utm.utm_source); // "newsletter"
Persisting UTM Parameters Across Pages
UTMs are only on the landing page URL. If you need them throughout the session (e.g., for form submissions), persist them to sessionStorage:
// On page load — capture and store UTMs
function captureUTMs() {
const params = new URLSearchParams(window.location.search);
const utmKeys = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];
utmKeys.forEach(key => {
const value = params.get(key);
if (value) {
sessionStorage.setItem(key, value);
}
});
}
// When submitting a form — read stored UTMs
function getStoredUTMs() {
const utmKeys = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];
return utmKeys.reduce((acc, key) => {
const value = sessionStorage.getItem(key);
if (value) acc[key] = value;
return acc;
}, {});
}
// Call on every page load
captureUTMs();
Passing UTMs to Your Backend
When users sign up, pass UTM data to your server so you can attribute conversions in your own database—not just in GA4.
// React form submission example
async function handleSignup(formData) {
const utms = getStoredUTMs();
await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
...formData,
acquisition: {
utm_source: utms.utm_source || 'direct',
utm_medium: utms.utm_medium || 'none',
utm_campaign: utms.utm_campaign || null,
referrer: document.referrer || null,
}
})
});
}
Next.js: Accessing UTM Params
// app/page.tsx — Server Component
import { headers } from 'next/headers';
export default function LandingPage({ searchParams }: {
searchParams: { [key: string]: string | undefined }
}) {
const utmSource = searchParams['utm_source'];
const utmMedium = searchParams['utm_medium'];
const utmCampaign = searchParams['utm_campaign'];
// Pass to analytics or use for personalization
return <div>...</div>;
}
// Client Component with useSearchParams
'use client';
import { useSearchParams } from 'next/navigation';
export function UTMCapture() {
const searchParams = useSearchParams();
const utmSource = searchParams.get('utm_source');
// Store to sessionStorage on mount
useEffect(() => {
if (utmSource) {
sessionStorage.setItem('utm_source', utmSource);
}
}, [utmSource]);
return null; // invisible tracking component
}
Common Mistakes to Avoid
1. UTM-ing internal links
Never tag internal links (links that go from one page on your site to another) with UTM parameters. Doing so overwrites the original session source, making it look like the user came from utm_source=internal instead of Google or wherever they actually came from.
<!-- Bad: internal link with UTM -->
<a href="/pricing?utm_source=homepage&utm_medium=cta">See Pricing</a>
<!-- Good: internal link without UTM -->
<a href="/pricing">See Pricing</a>
2. Ignoring URL encoding
Spaces and special characters must be URL-encoded. Most UTM builders handle this automatically, but if you’re constructing URLs manually:
const campaign = "spring launch 2025 - dev tools";
const encoded = encodeURIComponent(campaign);
// "spring%20launch%202025%20-%20dev%20tools"
// Or use URLSearchParams which handles encoding automatically:
const params = new URLSearchParams({
utm_source: 'newsletter',
utm_campaign: 'spring launch 2025'
});
// "utm_source=newsletter&utm_campaign=spring+launch+2025"
3. Using UTMs in social media bio links
Single-use profile links (like your Twitter bio) don’t need UTMs per click—they should use a UTM once. But utm_content helps if you A/B test different bios.
4. No UTM governance
Without a defined taxonomy and process, teams create duplicate campaigns, typos, and inconsistent casing. The result is fragmented data that’s hard to analyze.
UTM Parameter Quick Reference
| Parameter | Required | Purpose | Example |
|---|---|---|---|
utm_source | Yes | Where traffic comes from | google, newsletter |
utm_medium | Yes | The marketing channel | cpc, email, social |
utm_campaign | Yes | Campaign identifier | spring-sale-2025 |
utm_content | No | Differentiate links in same campaign | cta-header, cta-footer |
utm_term | No | Keyword (paid search) or segment | javascript+tools |
Tools for UTM Management
- UTM Campaign Builder — Build properly-formatted UTM URLs with consistent naming
- Google Analytics 4 — Primary destination for UTM attribution data
- Google Tag Manager — Advanced UTM capture and event tracking
- Bitly / Short.io — Shorten UTM-tagged URLs for social sharing
- Looker Studio — Build custom UTM attribution dashboards
Summary
UTM parameters are a foundational analytics tool that every developer should understand:
- 5 parameters: source (required), medium (required), campaign (required), content (optional), term (optional)
- Naming matters: always lowercase, hyphens over spaces, consistent taxonomy across your team
- GA4 integration: medium values should match GA4’s default channel grouping rules
- Persist across pages: use
sessionStorageto carry UTMs from landing page to conversion - Never UTM internal links: it corrupts session attribution
The 10 minutes you spend setting up proper UTM conventions will pay dividends in accurate attribution for months. Start with a UTM builder and document your taxonomy—your future self (and your marketing team) will thank you.
50 CLI Commands That Save Hours Every Week
The exact Git shortcuts, file search tricks, Docker commands, and productivity hacks that senior developers use daily. Compiled from 5+ years of shipping production code.
- Git mastery (10 cmds)
- File & search wizardry
- Docker & DevOps tricks
- Process & network tools
- Productivity boosters
- macOS & Linux install guide
No spam. 1 email/week max. Unsubscribe anytime.
Found this guide useful? Check out our free developer tools.
Affiliate disclosure: Some links below are affiliate links — we may earn a small commission at no extra cost to you. Learn more.
Recommended Tools & Resources
DigitalOcean
$200 credit for new users. Simple, affordable cloud hosting for developers.
GitHub Student Pack
Free access to 100+ developer tools. Perfect for students and new devs.
Vercel
Deploy frontend apps instantly. Free tier is generous for side projects.
DevPlaybook Products
Boilerplates, scripts & AI toolkits to 10x your dev workflow.