Skip to main content
Terminus
Contents
ReferenceCheat Sheet · ~24 min read

UTM Cheat Sheet: Values and Where to Click

Values for every channel, the field to put them in on Google Ads, Microsoft Advertising, Meta and LinkedIn, what each email platform writes, and the lookups for links on the way: anatomy, redirects, lead forms, test clicks and changing your taxonomy. Every vendor fact sourced and dated.

On this page

How to use this page

Find the channel, copy the values, and put them in the field named under the platform. Change the campaign value to your own; the rest is ready to use.

The values follow the book’s conventions (Chapter 3): lowercase, underscores inside a value, hyphens between segments, and campaigns in the [initiative]-[product]-[yyyy_mm] pattern. The examples are Stride’s, the book’s fictional shoe brand. Chapter 5 explains who writes each link; this page is the lookup.

Every vendor fact here (a menu path, a setting, a default, a limit, a behavior) carries a link to the vendor’s own documentation and the date we checked it. Vendors move their menus often. When a path has moved, the setting’s name usually hasn’t, so search the settings for it. A fact we couldn’t confirm in the vendor’s own pages isn’t on this page.

Choosing each value

Source

The source is the platform or property that sent the visit: google, facebook, instagram, linkedin, newsletter, promotional_email. Offline, it’s what carries the link: retail_display, direct_mail, print_ad, event. A source may carry one detail segment after its type, naming the third party that publishes the link: partner-acme, affiliate-jane_smith. Where your own printed material sits is a placement, in content. An email platform’s name (mailchimp, klaviyo) is never on the list; Chapter 5 shows where one comes from.

Each medium takes only some sources, so the list holds pairs as well as values. Stride’s: cpc with google; paid_social and social with facebook or instagram; email with newsletter or promotional_email; offline with retail_display. Two listed values can still make a wrong pair: newsletter / social files as Organic Social (Chapter 3).

Medium

The medium comes from one closed list, because analytics sorts visits into channels by it (Chapter 2):

MediumUse forGA4 channel
cpcpaid searchPaid Search
paid_socialpaid socialPaid Social
paid_videovideo adsPaid Video
socialorganic postsOrganic Social
videovideo descriptions, cardsOrganic Video
emailevery emailEmail
displaydisplay, bannersDisplay
affiliateaffiliate linksAffiliates
referralpartners, event appsReferral
audiopodcastsAudio
offlineQR codes, print, eventsUnassigned

The paid mediums land in their paid channel with a source of the matching kind (a search engine, a social network, a video site). offline is the deliberate exception: GA4 files it as Unassigned unless you add a custom channel group (GA4 Field Notes).

Campaign

The campaign is the initiative, the same string in every channel that promotes it: spring_sale-runners-2025_03. Every segment is present, with na when one doesn’t apply. The date is the launch, never the end: Stride uses the launch month, and a quarter (2025_q1) is the coarser choice. No platform or channel goes in it: those are source and medium. After a region is added (Chapter 10), the pattern is [region]-[initiative]-[product]-[yyyy_mm], with regions us, uk, europe and north_america.

When a campaign name needs more segments, the values tend to differ by business. Which segments to add, and in what order, is Chapter 4.

SegmentB2B softwareE-commerce
Initiativewebinar, launch, demand_genspring_sale, black_friday, clearance
Productapi, analyticsrunners, sandals
Objectiveawareness, conversion, retentionawareness, conversion, retention
Date2025_03 or 2025_q12025_03

An e-commerce product is a line, not a SKU. Regions are the same plain words in either: us, uk, europe, north_america. An audience goes in utm_term (Chapter 6), or in the campaign as a segment. Running many clients at once is the Agency Playbook.

Term

The term holds the keyword or the audience. In paid social and display it’s the ad set or ad group (Chapter 6), such as retargeting-cart_abandoners; in paid search, the keyword, such as running_shoes. On email, organic posts and QR codes there’s no keyword or audience to record, so it has nothing to hold.

Content

The content value tells apart several links or creatives inside one campaign, source and medium: [placement]-[element], plus -[variant] when testing (hero-image, cta-shop_now, video-testimonial-15sec). On an ad platform it’s the ad (Chapter 6). On printed material it names where the material sits: Stride’s QR code carries fleet_feet_nyc-qr_code, and every display gets its own value (Chapter 5). Content values typed without a pattern split one placement into several rows.

Values by channel

Values only, by slot: the source row is utm_source, and so on. The chapter named beside a value explains why it’s there.

SlotValue
sourcegoogle
mediumcpc
campaignspring_sale-runners-2025_03
term{keyword}
content{creative}

Name the Google Ads campaign spring_sale-runners-2025_03 as well: with auto-tagging on, GA4 shows the Google Ads campaign’s name instead of the link’s (Chapter 5), and the name is the join key for spend (Chapter 6). {keyword} and {creative} are ValueTrack parameters, listed under Google Ads below.

utm_source=google&utm_medium=cpc&utm_campaign=spring_sale-runners-2025_03&utm_term={keyword}&utm_content={creative}
SlotValue
sourcebing
mediumcpc
campaignspring_sale-runners-2025_03
term{keyword}
content{AdId}
utm_source=bing&utm_medium=cpc&utm_campaign=spring_sale-runners-2025_03&utm_term={keyword}&utm_content={AdId}

{Campaign} returns the campaign’s name, so it can fill utm_campaign when the Microsoft campaign carries the value. {AdId} is the ad, where Chapter 6 puts it; Microsoft’s own UTM tagging writes the ad group there instead (below).

Meta ads

SlotValue
sourcefacebook or instagram
mediumpaid_social
campaign{{campaign.name}}
term{{adset.name}}
content{{ad.name}}

Stride’s campaign is named spring_sale-runners-2025_03 and its ad video-testimonial-15sec, so those are the values that arrive (Chapter 6).

utm_source=facebook&utm_medium=paid_social&utm_campaign={{campaign.name}}&utm_term={{adset.name}}&utm_content={{ad.name}}

LinkedIn ads

SlotValue
sourcelinkedin
mediumpaid_social
campaign{{CAMPAIGN_NAME}}
term{{AD_SET_NAME}}
content{{AD_NAME}}

The same mapping as Meta’s, in LinkedIn’s names; the levels were renamed in October 2025 (below).

Retargeting

SlotValue
sourceinstagram
mediumpaid_social
campaignspring_sale-runners-2025_03
termretargeting-cart_abandoners
content{{ad.name}}

Retargeting is an audience, not a medium: the medium is the platform’s paid one, the campaign value is the initiative’s, the same as prospecting, and the audience goes in the term (Chapter 6) or in the campaign as a segment. On Google Ads, the medium is cpc or display.

Display

SlotValue
sourcegoogle
mediumdisplay
campaignbrand_awareness-lifestyle-2025_04
content300x250-sidebar-version_a

The source is the network serving the ad. Display bought through Google Ads with auto-tagging on takes its campaign from Google Ads in GA4, as search does (Google, checked 2026-10-06).

Newsletter

SlotValue
sourcenewsletter
mediumemail
campaignspring_sale-runners-2025_03
contenthero-image, cta-shop_now, footer-link

One content value per link. The campaign is the initiative the issue promotes, the same value as in every other channel.

Promotional email

SlotValue
sourcepromotional_email
mediumemail
campaignspring_sale-runners-2025_03
contentcta-shop_now, banner-hero

A separate source from newsletter keeps recurring and one-off email apart in a report.

Staff email signatures

SlotValue
sourceemail_signature
mediumemail
campaignthe initiative the signature’s link promotes
contentsignature-sales_team, signature-support_team

Tagged, signature clicks sit inside Email beside campaign email; filter the source out when you judge campaigns. Untagged, a click from a reply thread arrives with whatever referrer the mail app sends; email apps send none (Chapter 2).

Organic social

SlotValue
sourcefacebook, instagram, linkedin, twitter, tiktok
mediumsocial
campaignspring_sale-runners-2025_03
contentpost-image, bio-link, story-link_sticker

social, not paid_social: an organic post belongs in Organic Social.

QR code

SlotValue
sourceretail_display
mediumoffline
campaignspring_sale-runners-2025_03
contentfleet_feet_nyc-qr_code

Printed as the short link stride.co/nyc25, whose redirect writes the tagged link (Chapter 5). The content names the display, so every display gets its own value. Several codes on one display add a variant: fleet_feet_nyc-qr_code-window, fleet_feet_nyc-qr_code-counter.

Direct mail

SlotValue
sourcedirect_mail
mediumoffline
campaignspring_sale-runners-2025_03
contentpostcard-version_a, catalog-page_3

Printed as a short link or a QR code, like the QR code above.

YouTube

SlotValue
sourceyoutube
mediumvideo for descriptions, cards and end screens; paid_video for ads
campaignbrand_awareness-lifestyle-2025_04
contentdescription-link_1, end_screen-cta, card-mid_video

Podcast

SlotValue
sourcepodcast-[show]
mediumaudio
campaignbrand_awareness-lifestyle-2025_04
contentshow_notes-link, spoken-cta

The show goes in the source’s detail segment: podcast-marketing_over_coffee. A spoken call to action needs an address someone can say: a short path such as stride.com/podcast, redirecting to the tagged link with utm_content=spoken-cta.

Affiliate and partner

SlotValue
sourceaffiliate-jane_smith, partner-acme
mediumaffiliate for affiliates, referral for partners
campaignspring_sale-runners-2025_03
contentsidebar-banner, text_link-review

When you make the links and hand them out, every affiliate’s values come off your list. When affiliates type their own, each one can add a new spelling.

Webinar or event

The campaign value is the same on every touchpoint; source and medium change with where each one lives. For a webinar, webinar-product_demo-2025_04. For an in-person event, event-sxsw-2025_03 on every link:

  • invitation email: promotional_email / email, content invite-cta
  • speaker announcement: linkedin / paid_social, content speaker-announcement
  • registration ad: google / cpc, content registration-ad
  • booth QR codes: event / offline, content booth-main_display and booth-demo_station
  • slides QR in a talk: event / offline, content session-slides_download
  • event app listing: event_app-sxsw / referral, content exhibitor-listing
  • follow-up and recording emails: promotional_email / email, content followup-day_2 and recording-link

Follow-up email tagged with the event’s campaign counts toward the event; tagged with another campaign value, its conversions count toward that one instead.

Variant tests

A test run through utm_content works on any channel you tag, and its results land in your analytics beside everything else. Each variant is a content value named for what changed:

What changesThe variants
CTA colorhero-cta-red, hero-cta-blue
CTA textcta-shop_now, cta-see_collection
Ad formatvideo-testimonial-15sec, image-product_shot
QR code spotfleet_feet_nyc-qr_code-window, fleet_feet_nyc-qr_code-counter
  1. Change one thing between the variants. The rest of the creative, the audience, the timing and the landing page stay the same.
  2. Give every variant the same source, medium, campaign and term. Only utm_content differs.
  3. Name each variant for what changed: hero-cta-red still explains the test a year later, and variant_a doesn’t.
  4. Two tests on the same source and medium at once leave a winner nobody can explain. Run them in sequence, or on different source and medium pairs, which a report keeps apart.
  5. Read the result: filter to the campaign, source and medium, break the report down by content, and compare sessions, conversion rate and revenue per session.

Ad platforms: where to click

Three fields take tracking parameters (custom parameters, tracking templates, checked 2026-10-06):

FieldWhat it does
Final URL suffixadds your parameters to the end of the landing page URL
Tracking templatewraps the landing page URL, with {lpurl} standing in for it
Custom parametersup to 8 of your own, used as {_name}; at any level except the account

Where each lives (Google, URL options, checked 2026-10-06):

  • the account: the Admin menu, Account settings, Tracking template
  • a campaign: its settings, Additional settings, Campaign URL options
  • an ad group: add the Tracking template column to the ad groups table, then edit it with the pencil icon
  • one ad: edit the ad and expand Ad URL options

The most specific level wins: keyword, then ad, ad group, campaign, account (Google, checked 2026-10-06). Changes at the account, campaign and ad group levels need no review; changes at the ad, keyword or sitelink level go through review (same page). Changes to tracking templates take 24 to 48 hours to reach ads serving (Google, checked 2026-10-06).

ValueTrack parameters fill in at click time, in single braces (Google, checked 2026-10-06):

ParameterReturns
{keyword}the keyword that matched the search; blank when an ad matched without one
{creative}the ad’s ID
{campaignid}the campaign’s ID (no parameter returns its name)
{adgroupid}the ad group’s ID
{matchtype}e exact, p phrase, b broad, a AI Max keywordless
{network}g Google search, s search partners, d Display; ytv, vp, gtv, x and e for YouTube, video partners, Google TV, Performance Max and app engagement
{device}m mobile, t tablet, c computer
{placement}the site where the ad was clicked
{loc_physical_ms}the click’s location, as an ID

With auto-tagging on, a click carries a gclid (Google, checked 2026-10-06), and GA4 builds source, medium and campaign from Google Ads; your term and content go to the Manual term and Manual ad content dimensions (Chapter 5, GA4 Field Notes).

Microsoft Advertising

The account’s tracking template: from the navigation menu on the left, hover over Campaigns, select Settings, Account level options, then Tracking template (Microsoft, checked 2026-10-06). Custom parameters take up to 8 key and value pairs on campaigns, ad groups, keywords and ads, 3 on sitelinks, and none on the account (Microsoft Learn, help, checked 2026-10-06).

On the same settings page, under Auto-tagging of UTM, Add UTM tags to my destination URLs tags links for you, either replacing all existing tags or keeping yours and adding any that are missing (Microsoft, checked 2026-10-06). On a search campaign it writes:

ParameterMicrosoft’s value
sourcebing
mediumcpc
campaignthe campaign
termthe keyword
contentthe ad group

Other campaign types get other values (msads and cpm on audience ads, for one), and for some accounts it adds utm_source_platform too, a feature Microsoft is still rolling out (same page). Its content is the ad group, where Chapter 6’s mapping puts the ad.

URL parameters, filled in at click time; they aren’t case-sensitive (parameters, case, checked 2026-10-06):

ParameterReturns
{Campaign}the campaign’s name
{CampaignId}the campaign’s ID
{AdGroup}the ad group’s name
{AdGroupId}the ad group’s ID
{AdId}the ad’s ID
{keyword}the keyword
{QueryString}the search query the person typed
{MatchType}e exact, p phrase, b broad
{Network}o Microsoft’s own (Bing, AOL, Yahoo), s search partners, a audience placements
{Device}m, t or c
{msclkid}Microsoft’s click ID, used for its conversion tracking (Microsoft, checked 2026-10-06)

Meta

Complete the ad’s creation steps until you reach Tracking. Below it, type the string into the URL parameters field, or click Build a URL parameter, then Apply (Meta, checked 2026-10-06). Meta appends the field to the Website URL, and where the same key appears in both, the field’s value wins (same page).

Dynamic parameters (Meta, checked 2026-10-06):

ParameterReturns
{{campaign.name}}the campaign’s name
{{adset.name}}the ad set’s name
{{ad.name}}the ad’s name
{{campaign.id}}, {{adset.id}}, {{ad.id}}the IDs
{{site_source_name}}fb, ig, msg, an or th (Threads)
{{placement}}the placement

{{site_source_name}} writes fb and ig, not the list’s facebook and instagram, so as a source it adds two spellings.

A name parameter keeps the name the campaign, ad set or ad had when the ad was first published, for that object’s whole life: a rename later doesn’t reach the links, and a new value needs a new campaign, ad set or ad (same page). So the name an object has at launch is the one that arrives.

LinkedIn

In Campaign Manager, select Advertise on the left, select the campaign on the Campaigns tab, then on the Ad sets tab move your cursor over the ad set’s name and click Edit (LinkedIn, checked 2026-10-06).

Static parameters can go on the account, the ad set and the ad; dynamic ones on the account or the ad set (LinkedIn, checked 2026-10-06; that page still calls the ad set a campaign, its name before the rename below). The dynamic parameters, in capitals and double braces: {{ACCOUNT_ID}}, {{ACCOUNT_NAME}}, {{CAMPAIGN_ID}}, {{CAMPAIGN_NAME}}, {{AD_SET_ID}}, {{AD_SET_NAME}}, {{AD_ID}}, {{AD_NAME}} (same page).

In October 2025 LinkedIn renamed its levels: the campaign group became the campaign, the campaign became the ad set, and the creative became the ad, and existing ad sets’ parameters updated themselves (LinkedIn, checked 2026-10-06). The Marketing API kept the old names, campaign groups, campaigns and creatives (Microsoft Learn, checked 2026-10-06), so a warehouse table built from the API can say “campaign” where Campaign Manager says “ad set”. Write down which level each export’s columns mean.

Levels and name limits

Every platform here stacks its ads in three levels. The top one’s name equals utm_campaign; the middle one, where the audience is chosen, maps to utm_term; the ad maps to utm_content (Chapter 6).

PlatformTop, middle, bottom
Google Adscampaign, ad group, ad
Metacampaign, ad set, ad
LinkedIncampaign, ad set, ad
TikTokcampaign, ad group, ad
Xcampaign, ad group, ad

Sources, checked 2026-10-06: Google, Meta, LinkedIn, TikTok, X API (which calls the ad group a line item).

Name length limits, where the vendor states one:

PlatformLimit
LinkedIncampaign names (the API’s campaign group): 200 bytes in UTF-8, which is 200 characters of a-z, 0-9, _ and - (Microsoft Learn)
Xcampaign names: 255 characters (X API)
Google Adscampaign and ad group names: 256 characters (Google Ads API)
Metaad set names: 400 characters; none stated for campaigns or ads (Meta)
TikTokcampaign names: 512 characters (TikTok)

All checked 2026-10-06. One campaign name runs on every platform, so it has to fit the strictest limit among the ones you use. Of these, that’s LinkedIn’s 200 bytes, on the campaign name, the one that must equal utm_campaign.

Email platforms

An email platform can tag links for you. Turned on while you also tag links yourself, it puts two writers on one slot: its value replaces yours, or sits beside it (Chapter 5). Here is what each one writes, where its setting lives, and what its help says about a link you already tagged. “Not stated” means the vendor’s help doesn’t say; send yourself a test and read a clicked link.

What each one writes

Mailchimp (help, checked 2026-10-06):

  • source, medium, content: not stated
  • campaign: a title you can edit, by default the email’s title combined with the date
  • in automation flows only, each parameter can be changed through Modify UTM Parameters
  • a link you already tagged: not stated; Mailchimp warns that combining its tracking with your own UTMs “could skew results” and recommends choosing one

HubSpot (traffic sources, tracking settings, checked 2026-10-06):

  • source, medium: not stated
  • campaign: the campaign the email is associated with; hs_email for a marketing email with none, hs_automation for workflow emails
  • content: a value HubSpot reads as the email’s name
  • a link you already tagged: your choice of three settings (below)

Klaviyo (help, checked 2026-10-06):

  • source: always on; the default isn’t stated (klaviyo is one of the static options)
  • medium: always on; since June 2, 2025 the default is the message type (email, sms, push, whatsapp), where it used to be campaign or flow; settings saved before then keep the old values
  • campaign, utm_id, term: each can be turned on or off
  • content: no built-in parameter; up to five custom parameters
  • a link you already tagged: not stated

Brevo (help, checked 2026-10-06):

  • source: always brevo, and it can’t be changed
  • medium: always email, and it can’t be changed
  • campaign: the campaign, workflow or template name, which you can edit
  • content and term: off by default; when on, one value per message, not per link
  • custom parameters: one on Professional, up to ten on Enterprise
  • a link you already tagged: not stated

ActiveCampaign (help, checked 2026-10-06):

  • source: ActiveCampaign with branding on, Newsletter with branding off
  • medium: email
  • campaign: the campaign name, which you can customize
  • content: the email’s subject line
  • a link you already tagged: not stated

Giving every slot one writer

Chapter 5 maps the three ways (you, the platform, or both on purpose). Two facts above decide what’s possible here: a platform’s tagging can stand in for yours only where it lets you write every slot your list needs (Brevo’s source is fixed as brevo, and none of these writes a content value per link), and HubSpot’s second setting tags only the links you haven’t. Tagging every link yourself, a recurring newsletter’s content values can sit in the email template by position (header-logo, hero-cta, article_1-read_more, footer-contact), with a merge tag for the campaign so it changes per send.

Where the settings live

Mailchimp

Checked 2026-10-06 (help). For a regular email: in the email builder’s Settings & Tracking section, check Google Analytics link tracking, then save. For an automation flow: Edit Settings, then check Google Analytics link tracking. In a flow, the three dots next to an email action open Modify UTM Parameters, with a dropdown per parameter.

HubSpot

Checked 2026-10-06 (help). Settings (the gear icon), Marketing, Email, the Tracking tab:

SettingWhat it does
Add source tracking tags to all URLsHubSpot’s tags on every link, overwriting yours
Add source tracking only if no existing tags in URLHubSpot tags only the links you haven’t
Don’t add source tracking tagsno automatic tagging

HubSpot’s tracking URL builder is under Settings, Tracking & Analytics, Tracking URLs, Create tracking URL. It makes the tagged URL and a short link, and HubSpot’s help says to use the full link, not the short one, in Google Ads (help, checked 2026-10-06).

Klaviyo

Checked 2026-10-06 (global settings, per message).

  • Global settings: your account name (bottom left), Settings, Other, UTM tracking.
  • Each parameter: a built-in Klaviyo option or your own static, dynamic or custom value, with different defaults for campaigns and flows.
  • A global change reaches every message that uses the global settings; messages with custom UTMs, or with tracking off, keep theirs.
  • One campaign: turn on Include tracking parameters, then Customize tracking parameters, or tick Do not use UTM tracking for this campaign.
  • One flow: one checkbox turns UTM tracking on, and Use custom tracking parameters sets the flow’s own values.

Brevo

Brevo’s help lists each parameter with whether it’s on by default and whether it can be edited; global settings apply to new campaigns, templates and automation messages (help, checked 2026-10-06).

ActiveCampaign

The account-wide setting is under Settings, Advanced, and a campaign’s name can be changed with Customize on its Campaign Summary page (help, checked 2026-10-06).

A link can change after you paste it: wrapped in a redirect, given an extra parameter, or stripped of its query (Chapter 5 explains the three kinds). These are the lookups for the route between your builder and the address bar.

WhereWhat happens to the link
Facebook, Instagram adsan ad click arrives with Meta’s click ID, fbclid (Meta, checked 2026-10-06)
Facebook, Instagramexternal links from ads and organic posts open in the in-app browser by default (Meta, checked 2026-10-06)
TikTokvisitors may open links in TikTok’s in-app browser (TikTok, checked 2026-10-06)
LinkedIna shared link longer than 26 characters is shortened when you post (LinkedIn, checked 2026-10-06)
Xevery link is shortened to a t.co link, with no opt-out (X, read from the archived copy of 2026-09-23 on 2026-10-06; the live page blocks automated reads)
Outlook desktopa URL that Safe Links wraps past Outlook’s 2,084-character limit is truncated; builds 16116.10000 and later raise the limit to 8,192 (Microsoft, checked 2026-10-06)
Email security scannersProofpoint URL Defense and Barracuda Link Protection rewrite links in email to point at their own redirect (Proofpoint, Barracuda, checked 2026-10-06)

A scanner’s wrapper makes a long link longer, so a tagged link near 2,084 characters can lose its end in Outlook.

Whatever the platform, the check is the same: click the published post or the sent email, not the raw URL, and read the address bar for every parameter, on a phone as well as a desktop.

URL anatomy and hygiene

A link has up to five parts, always in this order (RFC 3986, section 3). In https://stride.com/spring-sale?utm_source=newsletter#sizes:

  1. scheme: https
  2. host: stride.com
  3. path: /spring-sale
  4. query, after the ?: utm_source=newsletter
  5. fragment, after the #: sizes

Tags go before the #

The query starts at the first ? and ends at the first # (section 3.4), and everything after the # is the fragment, which is separated from the rest before the link is followed and read only by the browser (section 3.5). So in stride.com/spring-sale#sizes?utm_source=newsletter the tags are part of the fragment, and the link has no query at all. The working order is stride.com/spring-sale?utm_source=newsletter#sizes.

Safe characters in values

a-z, 0-9, _ and - (plus : in Key-Value names, Chapter 4). A space isn’t a character a URL can carry, so it travels percent-encoded as %20 (RFC 3986, section 2.1), and in a query a + is read as a space (WHATWG URL Standard). Underscores between words leave nothing to encode.

Hyphens in paths, underscores in values

Google’s search guidance recommends hyphens rather than underscores to separate the words of a URL (Google Search Central, checked 2026-10-06), so a page reads /spring-sale. That’s the path, the part a search engine reads as words. Tag values follow the book’s own rule instead: underscores inside a value, hyphens between segments (Chapter 3). The path is case-sensitive too: only the scheme and the host aren’t (RFC 3986, section 6.2.2.1).

What the browser’s referrer carries

With no policy set, browsers use strict-origin-when-cross-origin: a click from another site sends only that site’s origin (https://m.facebook.com, not the post), and a click from an HTTPS page to an HTTP one sends no referrer at all (MDN, W3C Referrer Policy, checked 2026-10-06). It’s why Chapter 2’s untagged clicks arrive as a bare domain, and why an http landing page gets no referrer from an https site.

A long tagged URL works, but it’s long to share, it can be cut off (the Outlook row above), and it makes a dense QR code: the more data a code holds, the more modules it needs and the larger the symbol (DENSO WAVE, checked 2026-10-06). A short link fixes the length, and it’s a redirect, so the tags arrive only if the redirect writes them (below). A branded short domain (stride.co/nyc25 rather than a shortener’s random path) tells people whose link they’re tapping. The shortener’s own click counts are its record, not your analytics’.

Tagged pages in search results

A tagged URL is a different URL from the same page untagged. Posted somewhere public, a search engine can find it as a duplicate. A rel="canonical" link on every page, pointing at its untagged URL, tells Google which version you prefer: <link rel="canonical" href="https://stride.com/spring-sale">. Google treats it as a strong signal, not a command (Google Search Central, checked 2026-10-06).

Sharing

A link someone pastes into a messaging app, a work chat or a personal email arrives with no tags, and, from an app that sends no referrer, files as direct (Chapter 2). These private shares are often called dark social. Two ways to shrink the blind spot, neither of which closes it:

  • Share buttons that add a source per network, such as utm_source=share-linkedin&utm_medium=social, so a shared link carries “shared, on LinkedIn” instead of nothing.
  • A “How did you hear about us?” question on your forms, which catches word of mouth no tag can; Chapter 11 sets it beside the other methods that fill the gaps in click tracking.

A redirect sends the browser to exactly the address it was set up with. The original query doesn’t carry over unless that address includes it; only a missing fragment is inherited (RFC 9110, section 10.2.2). A 301 is no safer than a 302 here. Shorteners, link-in-bio pages, vanity URLs and moved landing pages are all redirects, so:

  • Click through the whole chain and read the address bar at the end: the tags have to reach the final page, where analytics reads them.
  • When a landing page moves, update the links that point at it, or set up a redirect whose address keeps the query.
  • Now and then, click your most-used links and check that each still lands where it should, with every tag on it.

Chapter 9’s five breaks test what a tool refuses; one of them, a landing page that already has a query string, tests how it assembles a link. Three more construction tests belong beside it. Run them in a trial, on your own URLs, and read every link it gives you.

  1. Spaces and special characters: type a value with a space, or a character outside the safe set above, and check what the tool writes, and whether it lets the value through at all.
  2. A fragment: start from a URL with a # and check that the tags land before it.
  3. Volume: if you make links in bulk, make a batch the size of a real launch and check that every row comes out the way the first one did.

Capturing UTM values in lead forms

A form sends only its own fields, so the values a visitor landed with reach your CRM only if the site keeps them and copies them into hidden fields. Chapter 7 explains why; this is the recipe.

1. Keep the values when someone lands

A script reads the UTM parameters from the address and saves them in the browser. Where you save them decides how long they last:

Where the values are keptHow long they last
A session cookie (no Expires or Max-Age)until the browser ends the session; some browsers restore sessions, so it can last longer
A persistent cookieuntil the date in Expires, or for the period in Max-Age
Session storageuntil the page session ends
Local storageno expiry, until it’s cleared

All four belong to one browser on one device, and all four can be cleared. First touch has to survive across visits, so keep it in a persistent cookie or local storage. Last touch is rewritten on every tagged visit.

2. Add hidden fields to every lead form

One per value and per touch. A hidden field isn’t shown on the page and is sent with the form like any other field:

<input type="hidden" name="first_touch_utm_source">
<input type="hidden" name="first_touch_utm_medium">
<input type="hidden" name="first_touch_utm_campaign">
<input type="hidden" name="last_touch_utm_source">
<input type="hidden" name="last_touch_utm_medium">
<input type="hidden" name="last_touch_utm_campaign">

3. Fill the fields before the form is sent

From what step 1 saved. One script does steps 1 and 3:

<script>
(function () {
  var KEYS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];
  var params = new URLSearchParams(location.search);
  try {
    if (KEYS.some(function (k) { return params.has(k); })) {
      var touch = {};
      KEYS.forEach(function (k) { touch[k] = params.get(k) || ''; });
      // First touch: written once, never overwritten
      if (!localStorage.getItem('first_touch')) localStorage.setItem('first_touch', JSON.stringify(touch));
      // Last touch: rewritten on every tagged visit
      localStorage.setItem('last_touch', JSON.stringify(touch));
    }
  } catch (e) {}
  // Capture phase, so the fields are filled before the form's own handlers read them
  document.addEventListener('submit', function (e) {
    ['first_touch', 'last_touch'].forEach(function (set) {
      var saved = {};
      try { saved = JSON.parse(localStorage.getItem(set) || '{}'); } catch (err) {}
      KEYS.forEach(function (k) {
        var field = e.target.querySelector('input[type="hidden"][name="' + set + '_' + k + '"]');
        if (field) field.value = saved[k] || '';
      });
    });
  }, true);
})();
</script>

The script listens for submit on the page, so it won’t see a form inside an iframe, or a form sent by a script calling form.submit(), which raises no submit event (MDN, checked 2026-10-06); fill those fields another way, such as when the page loads.

Then give each hidden field a home in the CRM: a field per value and per touch, with the first-touch fields set never to be overwritten once filled. How each CRM does that is in The Tool Landscape.

Cookie lifetimes: MDN, Using HTTP cookies. Storage: MDN, Window.localStorage. Hidden fields: MDN, <input type="hidden">. Checked 2026-10-06.

Keeping test clicks out

Every test click on a tagged link lands in production analytics unless something keeps it out, and in a launch week that noise lands in the first numbers anyone reads. Four ways to keep it out of GA4:

MethodHow
Debug mode and a filterTurn on debug mode with Tag Assistant or preview mode and watch events arrive in DebugView (Admin, Data display, DebugView). Debug-mode events still reach your reports unless a Developer traffic data filter is active (DebugView, data filters, checked 2026-10-06).
Internal trafficDefine it (Admin, Data collection and modification, Data streams, your web stream, Configure tag settings, Show more, Define internal traffic), which only labels events with traffic_type. An Exclude data filter (Admin, Data collection and modification, Data filters) keeps them out, from its creation forward and permanently (internal traffic, data filters, checked 2026-10-06).
A separate test propertySend test traffic to its own property: the cleanest separation, and the most setup.
A test sourceTag test links utm_source=test and leave that value out of your reports, as long as test is never a real value.

A data filter can run in Testing first, which only marks matching data with the “Test data filter name” dimension, before you make it Active (Google, checked 2026-10-06).

When a report looks wrong

Start with the likeliest cause. Chapter 8’s audit finds most of these as a row that breaks the pattern, or a row no link explains.

What you seeCheck first
Campaign traffic missingtags after a #; a redirect dropping the query; a missing source, medium or campaign
One source on several rowscasing and spelling variants; an email platform’s tagging writing beside yours (Chapter 5)
The wrong source crediteda tagged internal link (Chapter 8); a platform or redirect rewriting the link
A lot of (not set)links shipped without a source, medium or campaign (GA4 Field Notes)
Paid clicks in an organic channela paid medium the channel rules don’t read as paid (Chapter 2); an untagged ad click

Changing your taxonomy

A one-page copy of Chapter 10’s four phases. Chapter 10 explains why a change is a period, with old and new formats side by side for as long as the longest-lived link stays in use; this is the checklist.

Before

  1. Write the change request, tied to the report that needs it.
  2. Inventory where the values are written (links in the wild, ad platform campaign names, templates) and every system that reads them (analytics and its reports, CRM fields, joins, dashboards).
  3. Build the mapping table (template below).
  4. Set the cutover date, for campaigns launching from then.
  5. Set the close criterion (samples below).
  6. Update every reader to read both formats, before anything new ships.

Cutover

  1. Change the tool so it offers only the new pattern and values.
  2. Write the changelog entry (template below).
  3. Send the news: link makers, then report readers, then agencies.
  4. Train link makers on one real campaign: show the approved values and the builder, then tag one campaign end to end (“We’re launching paid social for the fall sale in Europe. Here’s how you’d tag it.”).

Overlap

  1. Report on one combined view, or mark the break. Two formats mixed with no mark read as one.
  2. In every audit, check the old format’s share of new clicks.
  3. For each long-lived link still sending the old format, decide once: replace it or remap it.

Close

  1. Check the close criterion you set before the cutover.
  2. Retire the old format from new links, and keep it readable for history.
  3. Keep the mapping table for good.

The inventory misses these most easily:

  • email templates and email signatures
  • social bios
  • saved ad-platform URL settings (tracking templates, URL parameters)
  • printed codes: QR codes and short links on print
  • partner sites
  • the builder’s own saved templates

Changelog entry template

FieldExample (Stride’s region change)
Version2
Takes effectcampaigns launching from 2025_09
What changedthe campaign pattern gains a region: [region]-[initiative]-[product]-[yyyy_mm]
Mappingthree-segment names: region us, by lookup
Made byDana

Mapping table template

Old valueBecomesOld data reads as
lilinkedinremapped: it meant one thing
social, before the splitsocial or paid_sociala marked break: it held two meanings
a three-segment campaignfour segments, region firstregion by lookup: it follows from something recorded
no goal recordeda goal segmentunknown, never a guess

The message for each audience

  • Link makers: what changes on the form, from which date, and one example link in the new format.
  • Report readers: the date of the break, what compares across it (the combined view, or the sum), and where the changelog is.
  • Agencies: the new values or pattern, the cutover date, and where their links will come from (your builder, or finished links in the brief).

Sample close criteria

  • Every old-format click comes from a known, remapped link.
  • Every long-lived link in the inventory has been replaced or remapped.
  • A full audit cycle with no old-format clicks except from known long-lived links.
Next upWhen You Inherit a Mess