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_source
  • utm_medium
  • utm_campaign
  • utm_term
  • utm_content
  • gclid
  • fbclid
  • msclkid

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_source
  • utm_medium
  • utm_campaign
  • utm_term
  • utm_content
  • gclid
  • fbclid
  • msclkid

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_path as 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.md
  • metadata.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:

  1. Click the three-dot menu in the top-right corner.
  2. Select Import.
  3. Upload template.tpl.
  4. 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:

PlatformParameters to review
HubSpot_hsenc, _hsmi
Mailchimpmc_cid, mc_eid
Salesforce or Pardotcustom campaign IDs
Internal QAdebug, preview, test
CMS or site searchs, search, query

Be careful here.

Do not remove parameters that describe real user intent.

Examples to review carefully:

  • plan
  • product
  • location
  • category
  • language

Those may be useful in reporting.

Step 6: recommended configuration

For most teams, I would start with this:

SettingRecommended value
Return modePath and cleaned query
Remove URL fragmentEnabled
Additional parameters to removeAdd 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 URLExpected 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:

  1. Click the page view event.
  2. Open the Variables tab.
  3. Find Clean Page Path.
  4. 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 nameValue
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_location
  • page_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:

FieldValue
Dimension nameClean Page Path
ScopeEvent
Event parameterclean_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_location
  • page_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 PathViewsSessionsKey Events
/pricing1,24081096
/pricing?plan=pro43029041
/contact98067088

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:

CheckStatus
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.