GA4 Internal Traffic Exclusion Setup Guide

This guide explains how to set up internal traffic labeling and exclusion in Google Tag Manager (GTM) and GA4 for any website you manage.

This setup uses:

  • a special internal URL parameter
  • a first-party cookie
  • a lookup table variable in GTM
  • a GA4 configuration parameter
  • the built-in GA4 internal traffic filter

What this setup does

When someone visits a website with a special URL parameter, GTM stores a cookie in their browser. On future visits, GTM reads that cookie and sends traffic_type = internal to GA4. GA4 can then classify that traffic as internal and exclude it from reports.

Example flow

  1. A team member visits:
    https://www.example.com/?internal=true
  2. GTM detects ?internal=true
  3. GTM sets a first-party cookie named internal_user with the value true
  4. GTM reads that cookie on future pageviews
  5. GTM sends traffic_type = internal to GA4
  6. GA4 classifies the traffic as internal
  7. Once the filter is set to Active, GA4 excludes that traffic from future reporting

Important notes before you begin

  • This setup must be implemented separately in each GTM container / each site.
  • Team members must visit the internal link once per browser and device.
  • If someone clears cookies or changes browsers, they must visit the internal link again.
  • GA4 filters do not remove past data. They only affect future data.
  • Once the GA4 internal traffic filter is set to Active, excluded data is not available in reporting.
  • DebugView may still show internal events even after the filter is active.

Part 1: Build the GTM setup

Overview of what you will create in GTM

You will create:

Variables

  1. URL query variable to detect ?internal=true
  2. First-party cookie variable to read the internal cookie
  3. Lookup table variable to translate the cookie value into internal

Trigger

  1. Page View trigger that fires only when ?internal=true is present

Tag

  1. Custom HTML tag that sets the internal cookie

Existing GA4 / Google Tag update

  1. Update the main Google Tag so it sends traffic_type

Step 1: Create the URL variable

This variable checks whether the URL contains ?internal=true.

In GTM

Go to:
Variables → New

Configure the variable

  • Variable Name: Internal URL
  • Variable Type: URL
  • Component Type: Query
  • Query Key: internal

What this does

If the page URL is:
https://www.example.com/?internal=true

Then this variable returns:
true

Example screenshot placeholder


Step 2: Create the Page View trigger

This trigger fires only when the Internal URL variable equals true.

In GTM

Go to:
Triggers → New

Configure the trigger

  • Trigger Name: Pageview Internal Query True
  • Trigger Type: Page View
  • This trigger fires on: Some Page Views
  • Condition: {{Internal URL}} equals true

What this does

This ensures the cookie-setting tag only fires when someone lands on a page that contains ?internal=true.

Example screenshot placeholder


Step 3: Create the Custom HTML tag that sets the cookie

This tag writes a cookie to the browser when the internal URL is used.

In GTM

Go to:
Tags → New

Configure the tag

  • Tag Name: HTML Set Internal User Cookie
  • Tag Type: Custom HTML

Paste this code

<script>

(function() {

 var expires = new Date();

 expires.setFullYear(expires.getFullYear() + 1);

 document.cookie =

   “internal_user=true” +

   “; expires=” + expires.toUTCString() +

   “; path=/” +

   “; SameSite=Lax”;

})();

</script>

Triggering

Attach this trigger:

  • Pageview Internal Query True

What this does

When someone lands on a page with ?internal=true, GTM sets a cookie:

  • Cookie name: internal_user
  • Cookie value: true

The cookie lasts for one year unless the user clears cookies.

Example screenshot placeholder


Step 4: Create the first-party cookie variable

This variable reads the cookie that was set in Step 3.

In GTM

Go to:
Variables → New

Configure the variable

  • Variable Name: GTM Cookie Internal User
  • Variable Type: 1st Party Cookie
  • Cookie Name: internal_user

What this does

If the cookie exists, this variable returns:
true

Important note

The cookie name must exactly match the cookie set in the Custom HTML tag:

  • Tag writes: internal_user
  • Variable reads: internal_user

Example screenshot placeholder


Step 5: Create the lookup table variable

Do not use Custom JavaScript for this step. Use a Lookup Table. It is simpler and more reliable.

This variable translates the cookie value into the exact value GA4 expects.

In GTM

Go to:
Variables → New

Configure the variable

  • Variable Name: Internal Traffic Type
  • Variable Type: Lookup Table
  • Input Variable: {{GTM Cookie Internal User}}

Lookup Table row

  • Input: true
  • Output: internal

Default value

Leave blank.

What this does

If {{GTM Cookie Internal User}} = true, then:
{{Internal Traffic Type}} = internal

If the cookie does not exist, the variable returns blank.

Example screenshot placeholder


Step 6: Update the main Google Tag

This is the most important GTM update. Your main Google Tag must send the traffic_type parameter.

How to identify the correct tag

This is usually the base GA4 tag / Google Tag that fires on all pages.
Common signs:

  • Tag type is Google Tag
  • It uses a GA4 measurement ID like G-XXXXXXXXXX
  • It fires on Initialization – All Pages or All Pages

In GTM

Open the main Google Tag.

In Configuration Settings

Add a parameter row with:

  • Configuration Parameter: traffic_type
  • Value: {{Internal Traffic Type}}

Important details

  • Type traffic_type manually in the left field.
  • Do not choose it from the variable list.
  • It is a parameter name, not a variable.
  • The value should be the lookup table variable.

Final setup should look like this

  • traffic_type → {{Internal Traffic Type}}

What this does

If the cookie exists, GTM sends:
traffic_type = internal

to GA4 with events.

Example screenshot placeholder


Part 2: Test the GTM setup

Step 7: Preview the container

In GTM, click Preview.

Open the site and use the internal URL:
https://www.example.com/?internal=true

What to confirm in GTM Preview

A. Confirm the cookie-setting tag fired

Look for:

  • HTML Set Internal User Cookie
  • Status should be: Fired

B. Confirm the variables return the correct values

Open the Variables tab and confirm:

  • Internal URL = true
  • GTM Cookie Internal User = true
  • Internal Traffic Type = internal

If all three are correct, the GTM side is working.


Part 3: Verify the parameter in GA4

Step 8: Open GA4 DebugView

Go to:
GA4 → Admin → DebugView

With GTM Preview still active, generate a pageview or another event.

What to look for

Click a page_view event or another site event and review the event parameters.
You should see:

  • traffic_type
  • value: internal

What this confirms

This confirms GA4 is receiving the parameter.


Part 4: Register the custom dimension in GA4

Step 9: Create a custom dimension for traffic_type

This makes traffic_type available in reporting interfaces where supported.

In GA4

Go to:
Admin → Custom definitions → Create custom dimension

Configure the custom dimension

  • Dimension name: Traffic Type
  • Scope: Event
  • Event parameter: traffic_type

Save.

Important note

This may take several minutes to become available in reporting.


Part 5: Configure the GA4 internal traffic filter

Step 10: Open the internal traffic filter

In GA4, go to:
Admin → Data settings → Data filters

Open the built-in Internal Traffic filter.

Configure the filter

You should use:

  • Filter type: Internal traffic
  • Filter operation: Exclude
  • Parameter name: traffic_type
  • Parameter value: internal

Step 11: Set the filter state to Testing first

Choose:

  • Testing

Do not set it to Active immediately.

What Testing does

Testing mode allows GA4 to identify matching traffic without excluding it yet.


Part 6: Confirm GA4 is classifying the traffic

Step 12: Wait for data processing

After implementing the filter and custom dimension, wait a bit for reporting to catch up. DebugView is immediate, but standard reports can take longer.

How to confirm classification

Use one of these methods.

Preferred method

Go to a standard report and check whether internal traffic is being labeled.
Possible places include:

  • Reports → Engagement → Events
  • Add a secondary dimension where available
  • Use the test filter name / traffic type fields if supported

Important note

Realtime comparisons may not support this dimension. If GA4 says:
Realtime data is not supported for this comparison
that does not mean the setup failed.

If DebugView shows traffic_type = internal, the parameter is being received.


Part 7: Activate exclusion

Step 13: Change the GA4 filter from Testing to Active

Once you are confident the classification is correct, go back to:
Admin → Data settings → Data filters

Open Internal Traffic and change the filter state from:

  • Testing

to:

  • Active

What Active does

GA4 will exclude future events where:

  • traffic_type = internal

from reporting.

Important warning

This only affects future data.
It does not remove past data.
Once active, excluded internal traffic is not available in standard reporting.


Standard naming conventions to use on every site

To keep containers consistent, use the same names everywhere.

Variables

  • Internal URL
  • GTM Cookie Internal User
  • Internal Traffic Type

Trigger

  • Pageview Internal Query True

Tag

  • HTML Set Internal User Cookie

Using the same names across all sites will make maintenance easier.


Full implementation checklist

GTM

  • Create URL variable: Internal URL
  • Create trigger: Pageview Internal Query True
  • Create Custom HTML tag: HTML Set Internal User Cookie
  • Create 1st Party Cookie variable: GTM Cookie Internal User
  • Create Lookup Table variable: Internal Traffic Type
  • Update main Google Tag with traffic_type → {{Internal Traffic Type}}
  • Test in GTM Preview

GA4

  • Confirm traffic_type = internal in DebugView
  • Create custom dimension: Traffic Type
  • Set Internal Traffic filter to Testing
  • Confirm classification in reporting after processing
  • Change filter to Active

Troubleshooting guide

Problem: The cookie tag does not fire

Check:

  • Does the URL contain ?internal=true?
  • Does {{Internal URL}} return true?
  • Does the trigger use Page View and Some Page Views?
  • Is the condition {{Internal URL}} equals true?

Problem: The cookie exists, but GA4 is not receiving traffic_type

Check:

  • Does {{GTM Cookie Internal User}} return true?
  • Does {{Internal Traffic Type}} return internal?
  • Did you update the main Google Tag with:
    • traffic_type → {{Internal Traffic Type}}

Problem: traffic_type does not appear in the GA4 report builder

Check:

  • Did you create the custom dimension in GA4?
  • Has enough time passed for it to process?

Problem: Realtime report says the comparison is not supported

Important

This does not mean the implementation failed. Some dimensions are not supported in Realtime comparisons.
Use DebugView and standard reports for validation.

Problem: A team member is still being counted

Check:

  • Did they visit the internal link on that browser?
  • Did they clear cookies?
  • Are they using a different browser or device?

Internal link instructions for team members

Use this format for each site:

https://www.example.com/?internal=true

Team members should:

  1. Open the site using the internal link once
  2. Continue using the site normally after that
  3. Repeat if they clear cookies or switch browsers/devices

Recommended optional additions

These are not required for the basic setup, but they can improve reliability.

Option 1: Automatically classify GTM Preview / Tag Assistant users as internal

This helps prevent developers from accidentally appearing in live data.

Option 2: Maintain internal instructions in a central QA document

Keep a shared list of:

  • internal links by site
  • GTM container names
  • GA4 property names
  • implementation date
  • filter activation date

Option 3: Standardize QA after deployment

For every new site launch or container update, run this test:

  • Visit ?internal=true
  • Confirm cookie in GTM Preview
  • Confirm traffic_type = internal in DebugView

Final summary

This setup labels internal users using a one-time URL parameter and a cookie, then sends traffic_type = internal to GA4 so the built-in Internal Traffic filter can exclude those users from reporting.

The key components are:

  • URL variable
  • Page View trigger
  • Custom HTML cookie tag
  • 1st Party Cookie variable
  • Lookup Table variable
  • Google Tag configuration parameter
  • GA4 custom dimension
  • GA4 Internal Traffic filter

As long as each website uses the same structure and naming, this can be rolled out consistently across every property you maintain.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *