Bulk UTM builder template: one row per link, checked before you export
A spreadsheet template for bulk UTM links: the columns, a Google Sheets formula that handles ? and #, encoding, and checks before export.
On this page
- Columns for a UTM builder template
- Shared values and per-row values
- A Google Sheets formula for the final URL
- How a row becomes a URL
- Query first, fragment last
- The destination already has a query
- Encode values that contain delimiters
- A sample run
- Checks before you export
- Reuse the setup in UTMTool
- Sources
To build UTM links in bulk, give each link its own spreadsheet row: destination URL, utm_source, utm_medium, utm_campaign, and optional utm_content and utm_term. A formula then joins the pairs with & after a ? (Google's campaign URL guide (opens in a new tab)) and keeps them before any #, where RFC 3986 (opens in a new tab) ends the query. For setups you repeat, UTMTool saves a set of parameters as a template that you then select in the builder (paid plans).
Columns for a UTM builder template
One row per link: one destination for one placement. Use these columns, with values defined in Google's campaign URL guide (opens in a new tab):
| Column | Required | What goes in it |
|---|---|---|
A destination_url |
Yes | The full page address, starting with https:// |
B utm_source |
Yes | The referrer, for example google or newsletter4 |
C utm_medium |
Yes | The marketing medium, for example cpc, banner or email |
D utm_campaign |
Yes | The product, slogan or promo code, for example spring_sale |
E utm_content |
No | Differentiates creatives, such as two call-to-action links in one email |
Google says to always use utm_source, utm_medium and utm_campaign. Add a column for utm_term (the paid keyword) if you tag paid search links. The naming rules behind these cells (which sources and mediums your team uses, and how campaigns are spelled) belong in a naming worksheet; this page is about turning rows into links.
Build a campaign link
Create a UTM link with the free builder. No account needed.
Shared values and per-row values
Within one campaign, the campaign value is the shared one. Google recommends (opens in a new tab) one unique name that matches the exact campaign name, so a single effort does not split into several rows in reports: type it once and copy it down. Set source and medium for each placement, and use utm_content to separate links in the same placement.
A Google Sheets formula for the final URL
Add these three helper columns in row 2 and copy them down the sheet. Enter each destination in column A as a full https:// address.
F base_url =REGEXREPLACE(A2, "#.*$", "")
G fragment =IF(REGEXMATCH(A2, "#"), REGEXEXTRACT(A2, "#.*$"), "")
H final_url =F2 & IF(REGEXMATCH(F2, "\?"), "&", "?")
& "utm_source=" & ENCODEURL(B2)
& "&utm_medium=" & ENCODEURL(C2)
& "&utm_campaign=" & ENCODEURL(D2)
& IF(E2 = "", "", "&utm_content=" & ENCODEURL(E2))
& G2
What each function does, from Google's Sheets help (opens in a new tab), and what to use it for:
REGEXREPLACEreplaces part of a text string using a regular expression. Use it in column F to cut the#fragmentoff the destination.REGEXEXTRACT(opens in a new tab) extracts the first matching substring. Use it in column G to keep the#fragment, and addG2at the very end of column H.IF(opens in a new tab) returns one value if a logical expression is true and another if it is false. Use it in column G to return""for rows without a#.REGEXMATCH(opens in a new tab) tells you whether a piece of text matches a regular expression. Use it in column G to test for a#, and in column H to choose&when the destination already has a?, or?when it does not.ENCODEURL(opens in a new tab) encodes text so it can be used in the query string of a URL. Google's example encodes the texthello, world!ashello%2C%20world%21.
How a row becomes a URL
Query first, fragment last
RFC 3986 (opens in a new tab) orders a URI's components as scheme, authority, path, query and fragment. Section 3.4 (opens in a new tab) starts the query at the first question mark and ends it at a number sign (#) or the end of the URI. Section 3.5 (opens in a new tab) starts the fragment at the # and runs it to the end, and the fragment is separated from the rest of the URI before the URI is dereferenced.
So the UTM pairs go after ? and before #. A pair written after the # is part of the fragment, not the query. That is why the formula splits the fragment off first and appends it last.
Google's manual tagging steps (opens in a new tab) cover the rest: separate the parameters from the URL with a question mark, separate each parameter-value pair with an ampersand, and add the parameters in any order.
The destination already has a query
The query starts at the first question mark, and a question mark later on can be data within the query (section 3.4). A second ? does not start a new query, so join the UTM pairs to the existing one with &: example.com/webinar?lang=de becomes example.com/webinar?lang=de&utm_source=partner-blog-example&....
Encode values that contain delimiters
Section 2.2 (opens in a new tab) requires data that conflicts with a reserved character's purpose as a delimiter to be percent-encoded before the URI is formed. A percent-encoded octet is a % followed by two hexadecimal digits, and %20 is the percent-encoding for the space character (section 2.1 (opens in a new tab)). Encode a value like q&a recap before it goes into the URL: a plain & would read as the separator between two parameter-value pairs.
Letters, digits, hyphen, period, underscore and tilde are unreserved (section 2.3 (opens in a new tab)), and URI producers should not create percent-encoded forms of them. Values made only of those characters, like q4-webinar, need no encoding at all, which is one reason to prefer hyphens to spaces. The free UTM builder notes that spaces turn into %20 or + in links, and has an option to replace spaces with hyphens.
A sample run
Three rows for one webinar campaign.
Shown without https:// to fit; the destination column and every final URL include it.
| destination_url | utm_source | utm_medium | utm_campaign | utm_content |
|---|---|---|---|---|
example.com/webinar |
youtube |
video |
q4-webinar |
description-link |
example.com/webinar |
podcast-example |
audio |
q4-webinar |
show notes |
example.com/webinar?lang=de#agenda |
partner-blog-example |
referral |
q4-webinar |
agenda recap |
Shown without https:// to fit; every final URL includes it.
| Row | final_url (column H) |
|---|---|
| 1 | example.com/webinar?utm_source=youtube&utm_medium=video&utm_campaign=q4-webinar&utm_content=description-link |
| 2 | example.com/webinar?utm_source=podcast-example&utm_medium=audio&utm_campaign=q4-webinar&utm_content=show%20notes |
| 3 | example.com/webinar?lang=de&utm_source=partner-blog-example&utm_medium=referral&utm_campaign=q4-webinar&utm_content=agenda%20recap#agenda |
The last row puts the three cases above together: an existing query, a #fragment kept at the end, and a space encoded as %20.
Checks before you export
Run these on the sheet before anyone copies a link:
- No empty required cells. Missing UTM parameters (opens in a new tab) show up as (not set) in reporting.
- One spelling per value. Parameter values are case sensitive:
utm_source=googleandutm_source=Googleare different values, and so areMetaandmeta. The free UTM builder has a lowercase option; in the sheet, a lowercase formula on the value columns does the same job. - One campaign name. Every row of the campaign carries the same
utm_campaignspelling. - No duplicate rows. Sort the sheet by destination, source, medium and content, and remove any row that repeats another.
- Every final URL starts with
https://. Then paste thefinal_urlcolumn into the UTM link checker, one link per line and up to 50 links at a time, and open the exact link before sharing it with the campaign link preflight checklist.
Reuse the setup in UTMTool
The sheet plans the rows. To build the links with the same names every time, UTMTool has two levels:
- Free: create 25 new UTM links each month in one project, with the builder, saved parameters and the link library. Choose saved values in the builder, so every new link follows the names you already use.
- Paid plans: templates. Save a set of parameters as a template, then select it in the builder for repeat setups; keep each finished link in your library.
For each planned row, select the template or the saved values in the builder and add that row's destination. For a quick link without an account, the free UTM builder runs in your browser, with no signup, and your recent links stay on your device.
Sources
- Google Analytics: campaign URL parameters (opens in a new tab)
- RFC 3986, section 3.4: query (opens in a new tab)
- Google Docs Editors Help: REGEXREPLACE (opens in a new tab)
- Google Docs Editors Help: REGEXEXTRACT (opens in a new tab)
- Google Docs Editors Help: REGEXMATCH (opens in a new tab)
- Google Docs Editors Help: IF (opens in a new tab)
- Google Docs Editors Help: ENCODEURL (opens in a new tab)
- RFC 3986, section 3: syntax components (opens in a new tab)
- RFC 3986, section 3.5: fragment (opens in a new tab)
- RFC 3986, section 2.2: reserved characters (opens in a new tab)
- RFC 3986, section 2.1: percent-encoding (opens in a new tab)
- RFC 3986, section 2.3: unreserved characters (opens in a new tab)
Tools for this
-
Free UTM builder
Build a link with your campaign parameters.
-
UTM link checker
Check a tagged link and see which GA4 channel it lands in.
Frequently asked questions
Which values can be shared across every row?
Within one campaign, the campaign value: Google recommends one unique name that matches the exact campaign name. Source and medium describe each placement, and utm_content tells links in the same placement apart.
How do I keep an existing query string or #fragment on the destination?
Join the UTM pairs to the existing query with an ampersand, and keep the #fragment at the end: the query starts at the first question mark and ends at the number sign.
Are UTM values case sensitive?
Yes. utm_source=google is a different value from utm_source=Google, so pick lowercase spellings and use them in every row.
Build a campaign link
Create a UTM link with the free builder. No account needed.