Clean UTM Parameters in GA4 with Google Tag Manager
UTM parameters are useful for campaign tracking, but they can make page reports messy.
A single page like /pricing can show up as several different rows in GA4 or Looker Studio because every campaign, ad click ID, or tracking parameter creates a slightly different URL.
For example: /pricing?utm_source=chatgpt.com&gclid=123&plan=pro
A cleaner reporting version would be: /pricing?plan=pro
The page is still /pricing. The useful context, plan=pro, is still there. The tracking noise is removed.
The UTM and Referral Cleaner Variable is a Google Tag Manager custom variable template that returns a cleaner version of the current page path. You can use it to remove common tracking parameters like UTM values, ad click IDs, and other noisy query strings before sending a cleaner page path into GA4.
The goal is simple: make page-level reporting easier to read while keeping GA4’s standard attribution fields intact.
You can download the template here: UTM and Referral Cleaner Variable on GitHub
What this variable is for
Use this variable when page reports are being cluttered by tracking parameters.
This usually happens when pages appear multiple times because of values like:
utm_sourceutm_mediumutm_campaignutm_termutm_contentgclidfbclidmsclkid
Those parameters are useful for campaign and ad platform tracking. They are less useful when you are trying to answer a page performance question.
For example, you may want to know how /pricing performed overall. Instead, your report may show rows like:
/pricing?utm_source=google&utm_campaign=spring/pricing?utm_source=linkedin&utm_campaign=demo/pricing?gclid=123/pricing?fbclid=abc/pricing?plan=pro&utm_source=email
That makes the report harder to scan.
This variable gives you a cleaner page path that you can send into GA4 as a custom event parameter, such as: clean_page_path
Once it is registered as a GA4 custom dimension, you can use it in Explorations, Looker Studio, and custom reports.
What this variable cleans
The variable can remove common tracking parameters from the page path.
That includes UTM parameters and ad click IDs such as:
utm_sourceutm_mediumutm_campaignutm_termutm_contentgclidfbclidmsclkid
It can also preserve useful non-tracking query parameters.
Example: /pricing?utm_source=chatgpt.com&gclid=123&plan=pro
Becomes: /pricing?plan=pro
That matters because some query parameters describe the page experience. A parameter like plan=pro, category=books, location=toronto, or language=en may be useful in reporting.
The cleaner should remove tracking noise while keeping page context that still matters.
What this variable does not change
This variable only returns a cleaned path value.
It does not:
- store attribution
- replace GA4 campaign tracking
- change the browser URL
- remove parameters before the page loads
- clean URLs inside GA4 unless you send the cleaned value
- replace source, medium, or campaign reporting
Use this for cleaner page reporting. Keep campaign attribution handled through GA4’s source, medium, campaign, and attribution fields.
What you will set up
By the end of this setup, you will have:
- imported the GTM variable template
- created a Clean Page Path variable
- selected the return mode
- reviewed URL fragment handling
- added any extra parameters you want removed
- tested the variable in GTM Preview
- sent the cleaned value into GA4 as
clean_page_path - registered
clean_page_pathas a GA4 custom dimension - validated the setup in GA4 DebugView
- used the cleaner field in GA4 or Looker Studio reporting
Before you start
You need edit access to the correct Google Tag Manager container.
You also need permission to import custom variable templates, create variables, update GA4 tags, and publish or submit GTM changes.
From the GitHub repository, use the template.tpl file.
Do not import these into GTM:
README.mdmetadata.yaml
Those files are for documentation and template metadata.
Step 1: import the template into GTM
Open the correct Google Tag Manager container.
Go to:
Templates → Variable templates → New
In the template editor:
- Click the three-dot menu in the top-right corner.
- Select Import.
- Upload
template.tpl. - Save the template.
After saving, the custom variable template should appear as:
UTM and Referral Cleaner Variable
Step 2: create the GTM variable
Now create the variable that will return the cleaned page path.
Go to:
Variables → New
Name the variable:
Clean Page Path
Then click Variable Configuration and select:
UTM and Referral Cleaner Variable
This variable will return the cleaned version of the current page path based on the settings you choose.
Step 3: choose the return mode
The template has two return modes.
Path only
This returns only the page path.
Example: /pricing
Use this when you want all query parameters removed from page-level reporting.
This works well for:
- high-level content reporting
- simple page grouping
- dashboards where query details do not matter
Path and cleaned query
This returns the page path plus any remaining non-tracking query parameters.
Example: /pricing?plan=pro
Use this when some query parameters are meaningful.
This works well for:
- pricing pages
- product filters
- language variants
- form steps
- plan or version selectors
- landing pages where non-tracking parameters carry useful context
Recommended default:
Path and cleaned query
That setup keeps reporting cleaner without removing useful page context.
Step 4: decide whether to remove URL fragments
The template can also remove hash fragments.
Example with a fragment: /pricing?utm_source=chatgpt#features
If fragment removal is off, the cleaned value may keep the fragment: /pricing#features
If fragment removal is on, the cleaned value becomes: /pricing
For most GA4 reporting, I would enable fragment removal.
Fragments often create noisy rows like:
/page#section1/page#section2/page#faq
That can split one page into multiple rows even when the user is still on the same core page.
There are exceptions. If your website uses hash fragments as meaningful app states, keep them.
Examples where fragments may matter:
/app#billing/app#settings/app#users
If the fragment changes the user experience in a meaningful way, review it before removing it.
Step 5: add extra parameters to remove
Use Additional Parameters To Remove for custom query parameters that create reporting noise in your setup.
Example: _hsenc,_hsmi,vero_id,mc_cid,mc_eid
Use a comma-separated list: param1,param2,param3
Common examples by platform:
| Platform | Parameters to review |
|---|---|
| HubSpot | _hsenc, _hsmi |
| Mailchimp | mc_cid, mc_eid |
| Salesforce or Pardot | custom campaign IDs |
| Internal QA | debug, preview, test |
| CMS or site search | s, search, query |
Be careful here.
Do not remove parameters that describe real user intent.
Examples to review carefully:
planproductlocationcategorylanguage
Those may be useful in reporting.
Step 6: recommended configuration
For most teams, I would start with this:
| Setting | Recommended value |
|---|---|
| Return mode | Path and cleaned query |
| Remove URL fragment | Enabled |
| Additional parameters to remove | Add only known noisy parameters |
Recommended GTM variable name: Clean Page Path
This setup keeps the reporting cleaner while reducing the risk of deleting useful page context.
Step 7: test the variable in GTM Preview
Open GTM Preview mode and test URLs like these:
| Test URL | Expected Clean Page Path |
|---|---|
/pricing?utm_source=chatgpt&gclid=123&plan=pro | /pricing?plan=pro |
/about?utm_medium=email&utm_campaign=test | /about |
/contact?fbclid=abc123 | /contact |
/products?category=books&utm_source=google | /products?category=books |
/pricing#features | /pricing if fragment removal is enabled |
In GTM Preview:
- Click the page view event.
- Open the Variables tab.
- Find Clean Page Path.
- Confirm the returned value.
Test both simple and messy URLs.
The messy ones are where this variable earns its keep.
Step 8: send the cleaned path to GA4
Do not replace GA4’s standard page_location unless you have a very specific reason.
A safer setup is to send the cleaned path as a separate event parameter.
Open your GA4 page view or event tag and add:
| Parameter name | Value |
|---|---|
clean_page_path | {{Clean Page Path}} |
Recommended parameter name: clean_page_path
This keeps the original GA4 fields intact while giving you a cleaner reporting dimension.
The original fields still matter, especially for attribution and debugging.
Keep fields like these available:
page_locationpage_referrer- source
- medium
- campaign
The cleaned path should support reporting clarity without erasing the raw context.
Step 9: register clean_page_path in GA4
Once GA4 is receiving the parameter, register it as a custom dimension.
In GA4, go to:
Admin → Custom definitions → Create custom dimension
Use this setup:
| Field | Value |
|---|---|
| Dimension name | Clean Page Path |
| Scope | Event |
| Event parameter | clean_page_path |
Save it.
GA4 may take time before the new dimension appears in standard reports.
Once it is available, you can use it in Explorations, Looker Studio, and custom reports.
Step 10: validate in GA4 DebugView
Test with a URL like: /pricing?utm_source=chatgpt&gclid=123&plan=pro
In GA4 DebugView, confirm the event includes: clean_page_path = /pricing?plan=pro
Also confirm the original GA4 fields still exist separately.
Check for:
page_locationpage_referrer- source
- medium
- campaign
This gives you cleaner page reporting while keeping the original attribution context available.
Step 11: use it in Looker Studio
Once clean_page_path is available in GA4, use it in Looker Studio where raw page paths are too noisy.
For example, instead of using the raw page path dimension in a table, use Clean Page Path.
A cleaner table might look like this:
| Clean Page Path | Views | Sessions | Key Events |
|---|---|---|---|
/pricing | 1,240 | 810 | 96 |
/pricing?plan=pro | 430 | 290 | 41 |
/contact | 980 | 670 | 88 |
This makes page reporting easier to read because campaign parameters and click IDs are no longer splitting the same page into messy rows.
QA checklist
Before marking the setup complete, confirm the following:
| Check | Status |
|---|---|
| Template imported under Variable Templates | |
| GTM variable created | |
| Return mode selected | |
| Fragment removal reviewed | |
| Extra parameters reviewed | |
| UTM parameters are removed | |
| Click IDs are removed | |
| Non-tracking query parameters are preserved | |
| Meaningful parameters are not accidentally removed | |
clean_page_path added to GA4 tag | |
GA4 DebugView shows clean_page_path | |
| GA4 custom dimension created | |
| Looker Studio or reporting usage tested | |
| Attribution fields remain untouched |
Final note
Clean page reporting works best when you are selective.
Some query parameters are tracking noise. Others describe real page context, like plan type, product category, language, or location. Removing everything can make reports cleaner on the surface but less useful in practice.
The better approach is to remove the parameters that clutter reporting while preserving the ones that explain the page experience.