Skip to main content

Conversion Uplift

Track AI-Sourced Traffic with Google Tag Manager (Step-by-Step)

AI assistants and AI search engines (ChatGPT, Gemini, Perplexity, Copilot, etc.) increasingly surface and share your content. This guide shows how to track AI referrals in GA4 using Google Tag Manager (GTM) and GA4 with a clean dataLayer push, so multiple tags (GA4/Ads/Meta) can consume the same signal.

What you can use this for?

  • Measure AI visibility: See how often AI platforms send you traffic and which platforms matter most.

  • Content strategy: Identify pages most cited by AI tools and double down on those topics for SEO purposes.

  • Channel comparison: Compare AI-sourced sessions with Organic/Social/Direct for engagement and conversion.

  • Campaign targeting: Build audiences (e.g., “Came from ChatGPT”) for remarketing or personalisation.

 

How this differs from “AI snippet” GTM implementations?

  • AI snippet tracking (e.g., text-fragment #:~:text= / PAA/Featured Snippets) measures clicks from enhanced Google SERP features.

  • This method measures referrals from external AI platforms (ChatGPT/Gemini/Perplexity/Copilot/You.com/etc.), outside traditional search.

  • Use both to see the full picture: inside-Google AI features and off-Google AI platforms.

 

Overview of the approach:

  1. A CustomJavaScriptVariable detects AI platforms via document.referrer and UTM hints.

  2. A Custom HTML tag runs on DOM Ready and, if a match exists, pushes an ai_referral_detected custom event with parameters into the dataLayer.

  3. You create Data Layer Variables (DLVs) that read those parameters.

  4. A GA4 Event tag fires on the Custom Event (ai_referral_detected) and sends parameters to GA4.

  5. Make sure you register custom dimensions in GA4 and analyse. To minimise the number of new event scoped custom dimensions that you need to register, try and re-use some generic custom dimensions that you may use elsewhere, such as type and sub_type.

Step 1 — Create the detector (Custom JS Variable)

GTM → Variables → New → Custom JavaScript
Name: CJ AI Source Detector

function () {
try {
// — Helpers as function expressions (ES5-safe in blocks) —
var trim = function(s){ return (s || ”).replace(/^\s+|\s+$/g,”); };
var lc = function(s){ return (s || ”).toLowerCase(); };
var getQueryParams = function(href){
var params = {};
var q = href.split(‘?’)[1] || ”;
if (!q) return params;
var hashSplit = q.split(‘#’)[0] || q; // strip fragment
var parts = hashSplit.split(‘&’);
for (var i=0; i<parts.length; i++){
var kv = parts[i].split(‘=’);
if (!kv[0]) continue;
var key = lc(decodeURIComponent(kv[0]));
var val = ”;
try { val = lc(decodeURIComponent(kv.slice(1).join(‘=’))); } catch(e) { val = lc(kv.slice(1).join(‘=’)); }
params[key] = val;
}
return params;
};
var build = function(platform, method, pattern){
return {
platform: platform.name,
category: platform.category,
detection_method: method, // ‘referrer’ | ‘utm’
match_pattern: String(pattern),
referrer: String(document.referrer || ”),
utm_source: qp.utm_source || ”,
utm_medium: qp.utm_medium || ”,
utm_campaign: qp.utm_campaign || ”
};
};

// — Inputs —
var href = String(window.location && window.location.href || ”);
var ref = lc(String(document.referrer || ”));
var qp = getQueryParams(href);
var utmConcat = trim([qp.utm_source, qp.utm_medium, qp.utm_campaign].join(‘ ‘));

// — Catalog of AI platforms (extend anytime) —
var catalog = [
{ name:’ChatGPT’, category:’AI Chat’,
domains:[/chat\.openai\.com/], utm:[/chatgpt/,/openai/] },
{ name:’Claude’, category:’AI Chat’,
domains:[/claude\.ai/], utm:[/claude/] },
{ name:’Poe’, category:’AI Chat’,
domains:[/poe\.com/], utm:[/poe/] },

{ name:’Perplexity’, category:’AI Search’,
domains:[/perplexity\.ai/], utm:[/perplexity/] },
{ name:’Google Gemini’, category:’AI Search’,
domains:[/gemini\.google\.com/,/bard\.google\.com/], utm:[/gemini|bard/] },
{ name:’Microsoft Copilot’, category:’AI Search’,
domains:[/copilot\.microsoft\.com/,/bing\.com\/chat/], utm:[/copilot|bingchat/] },
{ name:’You.com’, category:’AI Search’,
domains:[/you\.com/], utm:[/youai|you\.com/] },
{ name:’Phind’, category:’AI Search’,
domains:[/phind\.com/], utm:[/phind/] },
{ name:’Kagi’, category:’AI Search’,
domains:[/kagi\.com/], utm:[/kagi/] },
{ name:’Brave (AI Summary)’, category:’AI Search’,
domains:[/search\.brave\.com/], utm:[/brave/] },
{ name:’DuckDuckGo (DuckAssist)’, category:’AI Search’,
domains:[/duckduckgo\.com/], utm:[/duckassist|ddg-ai/] },

{ name:’Meta AI’, category:’Assistant’,
domains:[/meta\.ai/], utm:[/metaai/] },
{ name:’Arc Search’, category:’Assistant’,
domains:[/arc\.net/], utm:[/arc/] }
];

// — 1) Referrer match —
for (var i=0; i<catalog.length; i++){
var p = catalog[i];
for (var d=0; d<p.domains.length; d++){
if (ref && p.domains[d].test(ref)) {
return build(p, ‘referrer’, p.domains[d]);
}
}
}

// — 2) UTM match —
if (utmConcat) {
for (var j=0; j<catalog.length; j++){
var q = catalog[j];
for (var r=0; r<q.utm.length; r++){
if (q.utm[r].test(utmConcat)) {
return build(q, ‘utm’, q.utm[r]);
}
}
}
}

// No detection
return null;
} catch (e) {
return null;
}
}

 

Step 2 — Push the event into the dataLayer (Custom HTML tag)

Create a new custom HTML tag in GA4 to push the parameters to the data layer. Use the DOM Ready trigger.

GTM → Tags → New → Custom HTML
Name: AI Referral – dataLayer push
Trigger: DOM Ready (once per page)

<script>
(function () {
try {
// prevent double-push on the same page
if (window.__aiReferralPushed) return;

var det = {{CJ AI Source Detector}}; // returns object or null
if (!det || !det.platform) return;

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: ‘ai_referral_detected’,
ai_source_platform: det.platform,
ai_source_category: det.category,
ai_detection_method: det.detection_method,
ai_match_pattern: det.match_pattern,
page_referrer: det.referrer || document.referrer || ”,
ai_utm_source: det.utm_source || ”,
ai_utm_medium: det.utm_medium || ”,
ai_utm_campaign: det.utm_campaign || ”
});

window.__aiReferralPushed = true;
} catch (e) {}
})();
</script>

If you enforce Consent Mode, add a consent check or fire this after consent is set.

Step 3 — Create Data Layer Variables (DLVs)

Create the following Data Layer Variables (DLV) by going to the User Defined Variables and use enter the following keys to capture the values:

  • ai_source_platform

  • ai_source_category

  • ai_detection_method

  • ai_match_pattern

  • page_referrer

  • ai_utm_source

  • ai_utm_medium

  • ai_utm_campaign

Step 4 — GA4 Event Tag

Here we create a new GA4 Event tag for ai_referral_detected and use this send new parameters to GA4.

Tag type: GA4 Event
Event name: ai_referral_detected
Trigger: Custom Event → Event name = ai_referral_detected


Event parameters:

ParameterValue
type{{ai_source_platform}}
sub_type{{ai_source_category}}
method{{ai_detection_method}}
pattern{{ai_match_pattern}}
page_referrer{{page_referrer}}
source{{ai_utm_source}}
medium{{ai_utm_medium}}
campaign{{ai_utm_campaign}}

Step 5 — Register GA4 Custom Dimensions

GA4 → Admin → Custom definitions → Create custom dimension (Scope: Event):

To help prevent GA4 running out of event scoped custom dimensions, we suggest you use some generic labels, such type, and subtype to minimise the need for registering new custom dimensions. If you are automatically exporting your GA4 data to BigQuery, you don’t need to register the parameter names if you don’t plan to analyse them in the GA4 console.

  • ai_source_platform → use the generic name of “type”

  • ai_source_category → use the generic name of “sub_type”

  • AI Detection Method →  use method

  • AI Match Patternuse pattern

(UTMs don’t need registering unless you want them in standard reports.)

Step 6 — QA & Debug

Test your set up in GTM Preview Mode and GA4DebugView before you publish.

  • GTM Preview: Load your site from an AI platform (or use a UTM test URL like
    https://yourdomain.com/?utm_source=chatgpt&utm_medium=aiassistant) and confirm the ai_referral_detected event appears with parameters.

  • GA4 DebugView: Check the event and parameters arrive.

  • Duplicates: The window.__aiReferralPushed guard helps avoid double pushes.

 

Step 7 — Analysing in GA4

Use the Explore reports section of GA4 to create custom reports. First add all the necessary custom dimensions to the Free Form report. This will allow you to add them to the report. Create segments based upon the source of traffic, including the event ai_referral_detected.

Explorations (Free Form):

  • Dimensions: AI Source Platform (type), Landing page + query string

  • Metrics: Sessions, Engagement rate, Conversions

  • Compare AI vs Organic/Direct segments.

Funnel/Pathing:

  • Entry by AI Source Platform (type) → subsequent pages → conversion.

Audiences:

  • Build an audience where event_name = ai_referral_detected to compare lifetime value or remarket.

Looker Studio (recommended visuals):

  • Time series by AI Source Platform (type) with a filter set for event name equals ai_referral_detected.

  • Top landing pages for AI referrals

  • Conversion rate by platform and landing page

Benefits of the dataLayer push approach

  • Multi-destination ready: The same event can feed GA4, Google Ads, Meta, or custom endpoints.

  • Debuggable: Easy to see in GTM’s Data Layer panel for QA.

  • Separation of concerns: Detection logic is isolated (variable), distribution is centralised (event).

  • Future-proofing: As new AI platforms emerge, update the catalog once; all tags keep working.

Notes & gotchas

  • SPAs: On single-page apps, also fire on “History Change” if navigation happens without reload.

  • Strict CSP: If inline scripts are blocked, convert the push into a template or use a GA4 tag with DLV mapping.

  • Consent Mode: Align firing with your consent policy.

  • Evolving ecosystem: Keep the platform catalog up-to-date.

Tracking visits and backlinks from AI tools is becoming an essential part of understanding how your content is discovered and shared in an AI-driven web. By setting up this GTM and GA4 framework, you’ll gain visibility into how platforms like ChatGPT, Gemini and Perplexity surface your site — giving you insights traditional analytics can’t.

If you’d like support implementing this or improving your GA4 and GTM setup, get in touch with the team at Conversion Uplift  by email [email protected]. We help businesses enhance data quality, streamline analytics, and uncover opportunities that drive measurable growth.

Neal Cole

Neal Cole

Neal is the founder of Conversion Uplift and the author of the official GA4/GTM audit course for CXL. It's the course much of the industry trains on. He's spent over 20 years in digital analytics, including senior roles in online gaming and financial services, working out where businesses' numbers go wrong and what it costs them. His work now focuses on server-side tracking, GA4 and BigQuery: getting the data right, and being the person who's accountable for it when a decision depends on it.
Neal Cole

Neal Cole

Neal is the founder of Conversion Uplift and the author of the official GA4/GTM audit course for CXL. It's the course much of the industry trains on. He's spent over 20 years in digital analytics, including senior roles in online gaming and financial services, working out where businesses' numbers go wrong and what it costs them. His work now focuses on server-side tracking, GA4 and BigQuery: getting the data right, and being the person who's accountable for it when a decision depends on it.
Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors

Free audit checklist to

Fix GA4 Tracking Like a Professional

Acceptance
Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors

Free audit checklist to

Fix GA4 Tracking Like a Professional

Acceptance