Skip to content

The New Google Tag

People hear “Google Tag” and assume it is just a rename of gtag.js. It is, and it is not. The file on the wire is still called gtag.js and still exports the same gtag() function. What changed in 2022 is that Google introduced a server-side configuration object — the Google Tag — that lives in the Google Tag admin UI, and a single Tag ID can now fan out to multiple Google destinations without you ever touching the HTML snippet.

That distinction sounds academic. It is not. It means tags can start firing on your site without anyone editing your codebase, because the fan-out is configured in Google’s admin, not in your page.

Valid as of April 2026, Google Tag (gtag.js).

The Google Tag is a configuration entity. It has:

  • A Tag ID (either G-XXXXXXXXXX for GA4 or GT-XXXXXXXXXX for the unified format)
  • One or more linked destinations — GA4 properties, Google Ads accounts, Floodlight activity groups, Campaign Manager 360 advertisers
  • A set of shared configuration — consent settings, user properties, default parameters

The loader script, gtag.js, fetches that configuration at runtime and fires whatever tags the admin says to fire. You install one snippet; Google decides what it does.

Two names, two things. The mental model matters for debugging.

gtag.js (the loader)

A JavaScript file served from googletagmanager.com/gtag/js?id=.... It exposes the global gtag() function, sets up the dataLayer queue, and handles network requests to Google’s collection endpoints.

One file, versioned by Google. You do not configure it beyond the id query parameter.

The Google Tag (the config)

A record in the Google Tag admin UI (Google Ads, GA4, or the standalone Tag Manager admin). It holds the Tag ID, the linked destinations, and shared settings like consent configuration.

You configure this. The loader reads it at runtime.

Same file on the wire. Different mental model. When a tag “fires” you are seeing gtag.js execute a decision made by the admin-side Google Tag.

This is the part that catches people out. When gtag.js initializes with a Tag ID, it does not just set up that one destination. It chains.

Simo Ahava has reverse-engineered this flow in detail, and the short version is:

  1. The page loads https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX.

  2. The returned script includes — or fetches — the list of linked destinations for that Tag ID.

  3. For each linked destination that is not already present, gtag.js injects an additional <script> tag or fetches an additional configuration bundle.

  4. A config command fires for each destination. GA4 sends its initialization page_view. Google Ads fires its remarketing page_view. Floodlight fires its global site tag.

  5. From that point on, any gtag('event', ...) call is evaluated against every linked destination. One event call, many collection endpoints.

The practical consequence: if you install a single GA4 snippet and someone later links a Google Ads account to that Tag ID in the admin UI, Ads remarketing pixels will start firing on your site. No code change on your side. No deploy.

Time (ms) Request
───────── ──────────────────────────────────────────────
0 Browser parses HTML, encounters gtag.js snippet
~50 GET googletagmanager.com/gtag/js?id=G-XXXX
~200 Script executes, reads linked destinations
~210 Additional bundle(s) fetched for linked Ads/Floodlight
~250 config('G-XXXX') → GA4 page_view
config('AW-YYYY') → Ads page_view
config('DC-ZZZZ') → Floodlight global site tag
~300+ Subsequent gtag('event', ...) calls fan out

Two commands, two roles.

CommandPurposeFires how often
gtag('config', 'G-XXXX', {...})Initialize a destination — cookies, session, first page_viewOnce per destination per page load
gtag('event', 'name', {...})Send a named event to all matching destinationsEvery time you call it
// Initialization — once per destination
gtag('config', 'G-XXXXXXXXXX', {
send_page_view: true,
user_id: 'user_123'
});
// Event — sent to every linked destination that matches
gtag('event', 'purchase', {
currency: 'USD',
value: 49.99,
transaction_id: 'T_12345'
});

You rarely write config calls by hand any more. The snippet Google gives you already includes one, and the auto-loading behaviour issues the rest. event is the call you actually make from your site’s code.

The Google Tag works in two architectures. They share the same runtime — they differ only in who owns the snippet.

You install gtag.js directly. This is the right choice for small sites that need GA4 plus maybe Google Ads and nothing else.

<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
</script>

The linked destinations are configured in the Google Tag admin. No GTM container. No trigger system. Pros: simple, fast, no GTM overhead. Cons: no custom triggers, no dataLayer transformation, no non-Google vendors.

A few consequences worth internalizing.

Auditing is a two-place job. Inspecting the HTML and the GTM container used to be enough. Now you also need to check the Google Tag admin for linked destinations. A site with one G- snippet can be firing four separate Google vendors.

“Removing the snippet” is not always enough. If you delete the GA4 inline snippet but leave a Google Ads conversion tag in GTM with the same linked Tag ID, the fan-out can still bring back the GA4 destination via the Ads side. Linked destinations are bidirectional.

Consent Mode applies globally. A single gtag('consent', 'default', {...}) call governs every linked destination. You do not need to call it per destination — but you do need to call it before gtag.js fires, or the auto-loaded destinations will read an undefined consent state.

Three tools, in order of usefulness:

  1. Tag Assistant (tagassistant.google.com). Shows every config call, every event, and — crucially — every linked destination that auto-provisioned.

  2. ?gtm_debug=x in the URL. Surfaces the GTM debug panel if GTM is on the page.

  3. Network tab, filtered to google-analytics.com/g/collect (GA4), googleads.g.doubleclick.net (Ads), and ad.doubleclick.net (Floodlight). Each destination has its own endpoint; counting the distinct endpoints tells you how many destinations the Tag fanned out to.

The same loader serves Ads and Floodlight. A gtag.js snippet with a G- ID can be firing three vendors. Check the admin.

Old setups often have one snippet from the GA4 admin and another from the Ads admin, both inline in the <head>. Modern gtag.js deduplicates the loader file itself, but the two inline gtag('config', ...) calls will both fire. Usually harmless, occasionally causes double page_view hits if both IDs are configured to send them.

If you delete your GA4 property but leave the Google Ads linked destination on the Tag ID, Ads remarketing keeps firing. The Tag ID is the primary key, not GA4.

Section titled “Not accounting for auto-loaded tags in Consent Mode”

A common bug: consent defaults are set correctly, but only for analytics_storage. The auto-loaded Ads destination reads ad_storage, which was never defaulted. Ads then defaults to granted and the implementation is non-compliant. Default all six Consent Mode v2 parameters before gtag.js runs.