10. Complete Guide on UTMs

THE COMPLETE

UTM TRACKING

PLAYBOOK

Building, Managing, and Troubleshooting UTM Parameters

Including GTM Integration, Klaviyo & Salesforce Platform Guides

SECTION 01 — Foundations

What Are UTM Parameters?

UTM stands for Urchin Tracking Module, named after . UTM parameters are small text snippets appended to URLs that tell your analytics platform where a visitor came from, how they got there, and which campaign drove them.

Without UTMs, Google Analytics can attribute traffic to a domain but cannot tell you which email, campaign, or creative drove the click. UTMs close that attribution gap completely.

Without UTMs vs. With UTMs

Source: email.mailprovider.com Medium: referral Campaign: (not set) Cannot tell which email or campaign drove the visit. Source: klaviyo Medium: email Campaign: summer-sale-2026 Know exactly which campaign and creative drove the visit.

ℹ Where to Find UTM Data in GA4

Go to Reports > Acquisition > Traffic acquisition to see Session source/medium, Session campaign, and all other UTM-driven dimensions.

SECTION 02 — Parameters

All UTM Parameters Explained

Google Analytics supports nine UTM parameters. The first three are essential for every URL. The remaining six add richer campaign context and are optional but recommended where applicable.

Parameter Required? Description Example
utm_source Required Identifies where your traffic originates — the publisher or platform sending visitors. google, klaviyo, facebook
utm_medium Required Identifies the marketing channel type. Feeds directly into GA4 Default Channel Groups. email, cpc, paid_social
utm_campaign Required Names the specific campaign. Use one consistent name to avoid fragmenting data. summer-sale-2026
utm_id Optional Unique campaign ID for cross-platform tracking and CRM matching. camp_2026_ss_001
utm_content Optional Differentiates links or creatives within the same campaign. hero-cta, sidebar-link
utm_term Optional Identifies paid search keywords. running+shoes+women
utm_source_platform Optional Identifies the buying/management platform directing traffic. Search Ads 360
utm_creative_format Optional Type of ad creative. Not yet reported in GA4 dimensions. display, native, video
utm_marketing_tactic Optional Targeting strategy applied to the campaign. remarketing, prospecting
⚠ Always Set All Three Required Parameters Together If you set utm_source but omit utm_campaign, GA4 will show (not set) for the campaign dimension. Source, medium, and campaign must always appear together in every UTM URL.

SECTION 03 — Structure

Anatomy of a UTM URL

A UTM URL is a normal URL with key-value pairs added after a ? character. Each pair is separated by &. Parameter order does not matter, but all three required parameters must always be present.

FULL UTM URL — ANNOTATED
https://www.yoursite.com/landing-page
?utm_source=klaviyo (WHERE traffic came from)
&utm_medium=email (HOW it was delivered)
&utm_campaign=summer-sale-2026 (WHICH campaign)
&utm_content=hero-cta (WHICH creative or link)
&utm_id=camp_001 (Campaign ID for CRM matching)
⚠ Case Sensitivity Warning UTM values are case-sensitive. utm_source=Google and utm_source=google create two separate rows in your reports. Always standardize to lowercase across your entire team.

SECTION 04 — Strategy

Naming Conventions & Best Practices

Inconsistent naming is the number one UTM problem. A single typo, capitalization difference, or synonym causes data fragmentation — the same campaign appears as multiple separate rows in your reports, making reliable analysis impossible.

Recommended Naming Formula

UTM CAMPAIGN TAXONOMY FORMULA
Formula: [platform]_[campaign-type]_[identifier]_[date]
Example: utm_campaign = fb_paid-social_summer-sale_jun2026
utm_source = facebook
utm_medium = paid_social
Parameter Rule
utm_source One source per platform. Always lowercase. facebook Facebook / FB / fb-ads
utm_medium Match GA4 default channel names. paid_social Paid Social / paidsocial
utm_campaign Hyphens, no spaces. Match platform name exactly. summer-sale-2026 Summer Sale / SummerSale
utm_content Unique per creative/link variant. hero-cta-v2 button / link1
utm_term Lowercase, use + for spaces. running+shoes Running Shoes

utm_medium Values Aligned to GA4 Default Channel Groups

GA4 Channel utm_medium Value Notes
Organic Search organic Matches utm_medium=organic with any source
Paid Search cpc Used with Google Ads, Bing. Medium must be cpc or ppc
Email email All email sends: newsletters, transactional, promotional
Paid Social paid_social Paid Facebook, Instagram, LinkedIn, TikTok, Pinterest
Organic Social social Organic posts, shares, profile links
Display Ads display Banner, interstitial, rich media display campaigns
Affiliates affiliate Commission-based partner links
Referral referral Links from other websites (non-social, non-search)
Push / SMS push or sms Mobile push notifications and SMS campaigns
Direct (none) No UTMs: user typed URL or used a bookmark

⚠ Avoid These Non-Standard Medium Values

Do not use banner, ad, sponsored, or paid as utm_medium values. They will not map to GA4 Default Channel Groups, sending traffic to the Unassigned channel and distorting your attribution data.

SECTION 05 — Tools

UTM Builder Tools

Never build UTM URLs manually at scale. These tools help you build, validate, and govern UTMs systematically, reducing errors and enforcing naming conventions across your team.

Official Google Tools

  • (ga-dev-tools.google/campaign-url-builder) Official Google tool for website UTM URLs. Best for one-off creation and team training.
  • Required for Android App Store campaign UTM tracking. Use this instead of the standard builder for any App Store URLs.
  • Team Management Tools

  • Team UTM management platform. Stores all UTMs in one place, enforces naming conventions, and integrates with major ad platforms.
  • Google Sheets + Validation Build a shared sheet with CONCATENATE formulas and Data Validation dropdowns that auto-generate and enforce UTM naming at scale.
  • Shortening & Testing

  • / Shorten long UTM URLs for social and SMS. Both preserve full UTM tracking. Rebrandly supports custom branded short domains.
  • GA4 DebugView Real-time UTM validation. Navigate to Configure > DebugView in GA4, or use the Google Analytics Debugger Chrome extension.

SECTION 06 — How GA4 Tracks UTMs

How GA4 Tracks UTM Parameters

Understanding the mechanics of how GA4 processes UTMs helps you debug issues and set appropriate expectations for reporting.

1 User Clicks a UTM Link The browser loads your page. The full URL including UTM parameters is visible in the address bar.
2 GA4 Tag Fires on Page Load Your GA4 snippet (via gtag.js or GTM) reads the URL query string and extracts UTM values automatically on page load. No custom code is required for standard parameters.
3 Parameters Stored at Session Level GA4 stores UTM data at the session level. All hits in that session are attributed to the same source, medium, and campaign. If a user later returns via direct, a new session starts with new attribution.
4 Data Appears in Reports (24-48 Hour Delay) Standard reports have a processing lag. Use Realtime or DebugView for immediate validation. Full attribution data appears in acquisition reports after approximately 24 hours.
5 UTMs Are Stripped from Page Path Dimensions UTM parameters do not appear in Page path + query string or Landing page + query string. They appear in the Page location dimension and separately in Traffic acquisition report dimensions.

Finding UTM Data in GA4

  • Traffic acquisition: Reports > Acquisition > Traffic acquisition. Shows Session source/medium, Session campaign, Default channel group.
  • User acquisition: Reports > Acquisition > User acquisition. First-touch source/medium for new users specifically.
  • Explorations: Explore > Blank. Add UTM dimensions alongside conversion metrics for deep custom analysis.
  • DebugView: Configure > DebugView. Real-time parameter verification per device. Essential for QA and testing.

SECTION 07 — Klaviyo Platform Guide

Klaviyo has built-in UTM tracking — but default settings do not always match your GA4 taxonomy, and platform auto-tracking can conflict with manually set UTMs if both are enabled at the same time.

How Klaviyo Auto-UTM Works

Klaviyo automatically appends UTM parameters to all email and SMS links when UTM Tracking is enabled in account settings. Default values are:

KLAVIYO DEFAULT UTM PARAMETERS
utm_source = klaviyo
utm_medium = email
utm_campaign = {{ message.name }} // Exact campaign name from Klaviyo
utm_id = {{ message.id }} // Unique Klaviyo message ID
utm_content = {{ message.id }} // Same as message ID by default

Three Levels of UTM Configuration in Klaviyo

1 Account Level (Global) Account > Settings > Email > UTM Tracking. Toggle on and set default source, medium, and campaign values that apply to all emails unless overridden.
2 Campaign / Flow Level In the campaign builder, go to the UTM Tracking step. Override account defaults for this specific campaign using Klaviyo dynamic tags.
3 Link Level (Manual) In the email editor, manually add UTMs to specific links. This overrides both account and campaign-level settings for that link.

Recommended Klaviyo UTM Template

KLAVIYO — OPTIMIZED UTM SETUP
utm_source = klaviyo
utm_medium = email
utm_campaign = {{ message.name | slugify }} // Converts "Summer Sale" to "summer-sale"
utm_content = {{ block.id }} // Unique per content block
utm_id = {{ message.id }} // Unique Klaviyo message ID
// For flows:
utm_campaign = {{ flow.name | slugify }}
utm_term = {{ flow_message.position }} // Email position in flow

Common Klaviyo UTM Issues & Fixes

🔴 Klaviyo: Campaign names creating duplicates in GA4
CAUSE Klaviyo's default {{ message.name }} uses the exact name, including spaces and capitals. "Summer Sale" and "summer-sale" become separate campaigns in GA4. FIXES Use the | slugify filter: {{ message.name | slugify }}. This converts "Summer Sale 2026" to "summer-sale-2026" automatically. Apply the slugify filter in every UTM template across all campaigns and flows.
🔴 Klaviyo: UTMs not appearing in GA4
CAUSE 1 Cause A: Klaviyo click-tracking wraps URLs through its tracking domain. If this redirect strips query strings, UTMs are lost. CAUSE 2 Cause B: Manual UTMs and Klaviyo auto-UTM are both enabled on the same links, creating double parameters and malformed URLs. FIXES Never combine manual UTMs with Klaviyo auto-UTM. Choose one approach consistently. If using manual UTMs, disable Klaviyo auto-UTM at the account level. Test by copying the tracked URL from a test send and checking the browser address bar for correct parameters.
🔴 Klaviyo: SMS links missing UTMs
CAUSE Klaviyo UTM tracking for SMS is configured separately from email and is often left at platform defaults. FIXES Go to Account > Settings > SMS > UTM Tracking. Set utm_medium=sms, not email. Verify SMS links use unique utm_content values to distinguish from email clicks in the same campaign.
🟡 Klaviyo: Flow emails all show the same campaign name
CAUSE Using {{ flow.name }} makes all emails in a Welcome Series appear identical in GA4 — you cannot distinguish which email in the sequence drove conversions. FIXES Add utm_content={{ flow_message.position }} to differentiate by position in the flow. Alternatively, add a manual suffix at the individual message level: utm_campaign=welcome-series-email-2.

Klaviyo to GA4 Verification Checklist

Send a test email, click all links, check GA4 Realtime for correct source/medium/campaign

Verify no duplicate ? or & symbols appear in the tracked URL

Confirm Klaviyo click-tracking redirect passes query strings through to destination

Check utm_medium=email routes to the Email channel in GA4 Default Channel Groups

Verify flow and campaign UTMs use consistent naming conventions across both

SECTION 08 — Salesforce Platform Guide

Salesforce Marketing Cloud and Salesforce CRM interact with UTMs differently. The highest-value goal is passing UTM data captured from GA4 into Salesforce Lead records so Sales teams can see which campaigns generated each opportunity.

Part A: Salesforce Marketing Cloud (SFMC) UTMs

SFMC manages UTMs through Email Studio, Journey Builder, and a centralized Parameter Manager. Configuration level determines scope of application.

SFMC EMAIL STUDIO — PARAMETER MANAGER

Navigate to Email Studio > Admin > Parameter Manager to set default UTM values for all email links. SFMC uses AMPscript substitution strings for dynamic values.

SFMC RECOMMENDED UTM SETUP (AMPSCRIPT)
utm_source = salesforce-mc
utm_medium = email
utm_campaign = %%jobid%% // Unique Job ID per send
utm_content = %%_messagecontext%% // Message context type
utm_id = %%jobid%%
// With AMPscript variables:
utm_campaign = %%=v(@campaign_name)=%%
utm_content = %%=v(@content_variant)=%%

JOURNEY BUILDER UTMS

SFMC JOURNEY BUILDER — DYNAMIC UTMS
utm_source = salesforce-mc
utm_medium = email
utm_campaign = %%Journey_Name%%
utm_content = %%ActivityName%% // Email activity name within journey
utm_term = %%Journey_Version%% // For A/B journey testing

Part B: Passing UTM Data Into Salesforce CRM

Connecting the marketing touchpoint to the Salesforce Lead record lets your Sales team know exactly which campaign generated each lead, enabling true revenue attribution by campaign.

1 Add Hidden UTM Fields to Lead Capture Forms Add hidden input fields to every form: utm_source, utm_medium, utm_campaign, utm_content, utm_term. These auto-populate via JavaScript from the URL or cookie.
2 Create Custom Fields on Salesforce Lead Object In Salesforce: Setup > Object Manager > Lead > Fields & Relationships. Create custom text fields (255 chars): UTM_Source__c, UTM_Medium__c, UTM_Campaign__c, UTM_Content__c, UTM_Term__c.
3 Map Form Fields to Salesforce If using Web-to-Lead, map each hidden field to the corresponding Salesforce custom field. For Pardot, Gravity Forms, or other tools, configure field mapping in the integration settings.
4 Persist UTMs in Cookies for Multi-Page Journeys Store UTM values in a first-party cookie on first touch. Read the cookie when the form loads — even on a different page. See Section 10 for full implementation details.
JAVASCRIPT — AUTO-POPULATE HIDDEN UTM FORM FIELDS
const params = new URLSearchParams(window.location.search);
const keys = ["utm_source","utm_medium","utm_campaign","utm_content","utm_term"];
keys.forEach(key => {
const el = document.getElementById(key);
if (!el) return;
const fromUrl = params.get(key);
const fromCookie = getCookie(key);
if (fromUrl || fromCookie) el.value = fromUrl || fromCookie;
});
function getCookie(name) {
const match = document.cookie.match(new RegExp("(^| )" + name + "=([^;]+)"));
return match ? decodeURIComponent(match[2]) : null;
}

Common Salesforce UTM Issues & Fixes

🔴 SFMC: UTMs not appending to Journey Builder links
CAUSE Parameter Manager settings apply only to Email Studio sends by default — they do not automatically apply to Journey Builder activities. FIXES In each Journey Builder email activity, go to Email Properties > Tracking > URL Parameters and add UTMs explicitly. Add UTMs directly in link href attributes using AMPscript dynamic tags in email templates. Create a shared AMPscript snippet with your standard UTM template and include it in every email template.
🔴 Salesforce CRM: UTM fields empty on Lead records
CAUSE 1 Cause A: Hidden form fields are not being populated — JavaScript runs before URL parsing, or the form uses an iframe that does not inherit parent URL parameters. CAUSE 2 Cause B: The form tool field mapping does not include UTM custom fields, so data is not pushed to Salesforce. FIXES Test: append ?utm_source=test&utm_medium=test&utm_campaign=test to your form URL, submit, and check the resulting Lead record in Salesforce immediately. For Pardot, check field mappings at Account Engagement > Admin > Salesforce connector > Field mappings. Verify all Salesforce custom field API names match exactly — they are case-sensitive.
🔴 Salesforce: First-touch vs last-touch attribution conflict
CAUSE Cookie script overwrites UTM values on every visit. A lead who first came from organic and then clicked a paid ad will only have paid-ad UTMs stored. FIXES Create two sets of fields: First_Touch_UTM_Source__c (only set if empty) and Last_Touch_UTM_Source__c (always updated). For multi-touch attribution, use a dedicated tool (Triple Whale, Rockerbox, Northbeam) that integrates with both GA4 and Salesforce.
🔴 Pardot (Account Engagement): Tracking conflicts with GA4
CAUSE Pardot uses its own parameters (pi_list_email, pi_campaign) alongside UTMs. These can interfere with GA4 UTM session attribution. FIXES In GA4, add Pardot tracking parameters to the list of unwanted referrals to prevent self-referral issues. Ensure UTMs appear before Pardot parameters in the URL. Sync UTM fields from Pardot Prospect records to Salesforce Lead via the Account Engagement connector field mapping.

SECTION 09 — Advanced

Custom UTM Parameters & GA4 Custom Dimensions

Standard UTMs tell you source, medium, and campaign. But what if you also need to track product category, trip type, offer variant, or color at the URL level? Custom URL parameters, used alongside UTMs, enable this granular attribution.

What Are Custom URL Parameters?

Custom URL parameters are extra key-value pairs appended to a URL alongside standard UTMs. GA4 does not capture them automatically, but with a GTM + GA4 Custom Dimensions setup, they can be captured, stored, and reported like any other analytics dimension.

URL WITH CUSTOM PARAMETERS (TRAVEL CAMPAIGN EXAMPLE)
https://example.com
?utm_source=facebook
&utm_medium=paid_social
&utm_campaign=spring-getaways
&utm_content=ad-version-a
&trip_type=business-trip // CUSTOM parameter
&destination=london // CUSTOM parameter

4-Step Process to Track Custom Parameters

1 Create URLs with Custom Parameters Use UTM.io or your team spreadsheet to generate URLs with both standard UTMs and custom parameters. Document all custom parameter names in your taxonomy.
2 Capture Custom Parameters in GTM Create a URL Variable in GTM for each custom parameter: Variables > New > Variable Configuration > URL. Set Component Type to Query and enter the parameter name as the Query Key.
3 Configure Custom Dimensions in GA4 In GA4: Admin > Custom Definitions > Create Custom Dimension. Set Name, Scope (User for attribution continuity), and Event Parameter matching your GTM variable. GA4 supports up to 25 user-scoped custom dimensions.
4 Verify and Analyze Use GA4 DebugView and GTM Preview Mode to confirm parameters are captured. Build Exploration reports in GA4 using your custom dimensions alongside conversion metrics.

ℹ User-Scoped vs Event-Scoped Custom Dimensions

For marketing attribution, always use User-scoped custom dimensions. They persist throughout the user journey across multiple sessions. Event-scoped dimensions only capture data per individual interaction and cannot reliably support attribution analysis.

SECTION 10 — Advanced: Cross-Domain

Transferring UTM Parameters Across Domains with GTM

A common tracking gap occurs when you drive traffic to an intermediate landing page, and users then navigate to a second domain to convert (such as an app store, payment gateway, or partner site). GA4 attributes the conversion to the intermediate domain, erasing your original campaign UTMs.

When This Problem Occurs

  • You drive traffic to landingpage.com with UTM parameters in the URL.
  • The visitor clicks a CTA and is redirected to appstore.com or a payment page.
  • A conversion fires on the destination domain. GA4 credits the intermediate domain — not the original utm_source.
  • This happens when cross-domain tracking cannot be implemented on the destination — for example, Shopify App Store, Apple App Store, third-party booking platforms, or external payment processors.
ℹ This Is Plan B — Try Standard Cross-Domain Tracking First GA4 standard cross-domain tracking (using the _gl linker parameter) is always preferred. Use this GTM script method only when you cannot install GA4 or GTM on the destination domain.

GTM Solution — Version 2 (Recommended)

This script scans all links on your page. For any link pointing to a domain in your target list, it appends the UTM parameters from the current page URL before the user clicks through.

GTM CUSTOM HTML TAG — UTM TRANSFER SCRIPT
<script>
(function() {
var domainsToDecorate = [
"appstore.com", // Replace with your destination domain(s)
"domain2.net"
],
queryParams = [
"utm_medium",
"utm_source",
"utm_campaign",
"utm_content"
];
var links = document.querySelectorAll("a");
for (var l = 0; l < links.length; l++) {
for (var d = 0; d < domainsToDecorate.length; d++) {
if (links[l].href.indexOf(domainsToDecorate[d]) > -1
&& links[l].href.indexOf("#") === -1) {
links[l].href = decorateUrl(links[l].href);
}
}
}
function decorateUrl(url) {
url = (url.indexOf("?") === -1) ? url + "?" : url + "&";
var collected = [];
for (var i = 0; i < queryParams.length; i++) {
if (getQueryParam(queryParams[i])) {
collected.push(queryParams[i] + "=" + getQueryParam(queryParams[i]));
}
}
return url + collected.join("&");
}
function getQueryParam(name) {
if (name = (new RegExp("[?&]" + encodeURIComponent(name) + "=([^&]*)"))
.exec(window.location.search))
return decodeURIComponent(name[1]);
}
})();
</script>

GTM Trigger for This Script

  • Trigger Type: DOM Ready
  • Fire on: Some DOM Ready Events — Page URL matches RegEx: utm_medium=|utm_source=|utm_campaign=
⚠ Known Limitations This script does not work if destination URLs contain a hashmark (#). It also does not stitch GA4 sessions across domains — the user starts a new session on the destination. Only campaign attribution is preserved, not user identity.

SECTION 11 — Advanced: Cookies

Saving UTM Parameters in Cookies for Form Attribution

UTM parameters are stripped from the URL as soon as a user navigates to a second page. If your lead capture forms are on a different page from the landing page, UTM data is lost before the form is submitted. The solution: store UTM values in a first-party cookie on landing, then read the cookie to auto-populate hidden form fields.

The Problem

  • User clicks a UTM link and lands on page 1 — parameters are visible in the URL.
  • User navigates to page 2 — URL parameters are dropped by the browser.
  • User fills in a form on page 2. Hidden UTM fields are empty because parameters are gone.
  • CRM record is created with no source, medium, or campaign data.
  • GTM Solution — Persist Campaign Data Template

1 Install "Persist Campaign Data" Template In GTM, go to Templates > Search Gallery. Search for Persist Campaign Data (by Simo Ahava). Add to your workspace. This template reads UTM parameters from the page URL and writes them to a browser cookie.
2 Create a Tag with All Pages Trigger Go to Tags > New > Tag Configuration > select Persist Campaign Data. Enter the parameters to store: utm_source, utm_medium, utm_campaign, utm_content, utm_term. Set trigger to All Pages.
3 Create a 1st Party Cookie Variable Variables > New > Variable Configuration > 1st-Party Cookie. Name it matching the cookie created by the template. Enable URL-decode cookie option so the stored URL is decoded for easy parsing.
4 Add Hidden UTM Fields to All Forms Add hidden input fields to every lead form with these names: source, medium, campaign, content, term. Set default fallback values (e.g., Organic, Website Form) for when no UTMs are present.
5 Add Custom HTML Tag to Populate Form Fields Create a new GTM Custom HTML tag with the population script below. Set trigger to All Pages. This reads the cookie on every page and fills form fields whenever UTM data is present.

COOKIE POPULATION SCRIPT (GTM CUSTOM HTML TAG)

(function () {

var value = "{{1st Party Cookie for persist}}";

if (!value) return;

function getUTMParameter(url, param) {

try {

return new URLSearchParams(new URL(url).search).get(param);

} catch (e) {

return null;

}

var utmSource = getUTMParameter(value, "utm_source");

var utmMedium = getUTMParameter(value, "utm_medium");

var utmCampaign = getUTMParameter(value, "utm_campaign");

var utmContent = getUTMParameter(value, "utm_content");

function populateFields() {

var map = {

source: utmSource,

medium: utmMedium,

campaign: utmCampaign,

content: utmContent

};

for (var key in map) {

if (!map[key]) continue;

var fields = document.querySelectorAll("input[name='" + key + "']");

for (var i = 0; i < fields.length; i++) {

fields[i].value = map[key];

}

}

}

populateFields();

// Re-trigger for dynamically injected forms (e.g. popups)

var observer = new MutationObserver(populateFields);

observer.observe(document.body, { childList: true, subtree: true });

})();

💡 First-Touch vs Last-Touch Attribution

Only write the cookie if it does not already exist to preserve first-touch attribution. For last-touch, always overwrite. For full multi-touch attribution, use a dedicated tool (Triple Whale, Northbeam, Rockerbox) that integrates with both GA4 and Salesforce.

SECTION 12 — Troubleshooting

Fixing Common UTM Problems

🔴 UTM traffic showing as "direct" in GA4
CAUSE Redirects stripping UTM parameters. When a UTM URL gets 301/302 redirected, parameters may be dropped before GA4 fires on the final page. FIXES Ensure your redirect passes query strings. In .htaccess, add the QSA flag to your RewriteRule — this flag preserves all query string parameters through the redirect. Link directly to the final destination URL, bypassing redirects entirely where possible. Test the full redirect chain: paste the UTM URL in a browser, follow all redirects, and check the final address bar URL contains intact parameters. Verify UTMs are not being stripped by a CDN, load balancer, or reverse proxy.
🔴 Campaign shows as "(not set)" in reports
CAUSE A UTM link had utm_source and utm_medium but was missing utm_campaign, or the parameter name was misspelled. FIXES Always set all three required parameters together: source, medium, and campaign. Validate every URL before sending using the Google Campaign URL Builder or your team spreadsheet. Audit live emails and ads with the GA4 Debugger Chrome Extension before launch.
🔴 Duplicate campaigns in reports ("Summer Sale" and "summer-sale")
CAUSE Different team members used different naming conventions, or a platform used title-case where your standard is lowercase. FIXES Implement a shared UTM taxonomy spreadsheet with dropdown validation to enforce naming conventions. In GA4, create a Custom Channel Group or use Data Transformation rules to merge duplicate campaign name variants. Use a Lookup Table variable in GTM to normalize incoming UTM values before they hit GA4.
🔴 Traffic going to "Unassigned" channel group
CAUSE The utm_medium value does not match any of GA4's Default Channel Group rules. For example, using utm_medium=banner instead of display. FIXES Remap all utm_medium values to match GA4 channel rules — see the channel mapping table in Section 4. Create a Custom Channel Group in GA4 Admin > Data Display > Channel Groups to capture any non-standard mediums. Historical data cannot be reprocessed — fix going forward and add a GA4 annotation noting the date of change.
🔴 UTMs not passing through iframes or app webviews
CAUSE Embedded iframes and app webviews often strip referrer information and query strings, breaking the attribution chain. FIXES For webviews, use gtag("set") to manually set campaign parameters on the page. Pass UTM parameters as explicit URL parameters in the iframe src attribute. Use GA4 Measurement Protocol to send hits server-side with full attribution context preserved.
🟡 UTMs appearing in GA4 page path reports
CAUSE You are looking at the Page location dimension, which includes full URLs with parameters. This is expected behavior. FIXES This is not a bug. UTMs are intentionally excluded from page path dimensions to avoid inflating unique page counts. Use the Traffic acquisition report for UTM-based analysis, not the Pages and screens report. For filtered page analysis by campaign, build an Exploration using both page path and UTM dimensions.

SECTION 13 — Checklist

Complete Implementation Checklist

Use this checklist before launching any new campaign and as part of regular UTM governance audits.

One-Time Setup

Created a shared UTM taxonomy document with approved values for source, medium, and campaign format

Implemented dropdown validation in the UTM spreadsheet to prevent typos

Established lowercase-only, hyphen-separated naming convention documented for all teams

Created custom UTM fields on Salesforce Lead object (if applicable)

Set up hidden UTM fields on all lead capture forms with JavaScript auto-population

Configured UTM cookie persistence script for multi-page journeys

Verified GA4 channel grouping rules align with all utm_medium values in use

Configured Klaviyo or SFMC UTM templates at the account/global level

Per Campaign

Built all UTM URLs using the team spreadsheet or approved builder tool

Verified all three required parameters are present: source, medium, campaign

Tested at least one UTM URL in GA4 Realtime or DebugView before launch

Confirmed no redirects strip UTM parameters across the full redirect chain

Verified platform auto-UTM is not double-applying on top of manually set params

Confirmed utm_content values are unique per creative or link variant

Added a GA4 annotation noting the campaign start date

Post-Campaign Audit

Checked Traffic acquisition report for expected source/medium/campaign appearance

Verified no (not set) campaign values appeared from this campaign

Confirmed Salesforce Lead records have UTM fields populated correctly

Reviewed for duplicate campaign name variants and fixed conventions going forward

Updated the UTM taxonomy document with any new approved values used in this campaign

💡 The Most Important Thing UTM discipline is a team sport. The biggest return comes not from perfect technical setup but from ensuring every person who creates links — marketing, sales, partnerships — uses the same naming system. A shared Notion or Confluence page with your taxonomy, examples, and the Google Sheets link will deliver cleaner data than any technical fix alone.

Quick Fix Request

Tell us about your tracking issue and we’ll get it resolved fast.