Skip to content
Black BoxPersonalization

dataLayer

Watch a push become a Google hit.

The queue, the tag, the consent gate, and the request to google-analytics.com. Consent off still shows the push, then stops it. Consent on shows the decoded collect hit beside the push that caused it.

What the dataLayer is

window.dataLayer is an array on the page. It is a queue, not a report. This site pushes commands onto it. The Google tag reads the queue and decides what, if anything, to send.

gtag() is a few lines installed before the Google script arrives: function gtag(){dataLayer.push(arguments);}. Calling gtag('event', 'page_view', { page_path: '/' }) appends those arguments to the array.

gtag.js then loads from googletagmanager.com and replaces dataLayer.push with its own function. Commands already waiting are handled in order. event becomes a measurement. consent changes the gate. config names the property and, here, sets send_page_view to false so a navigation is not counted twice. set stores a user property such as segments.

Consent Mode starts denied: analytics storage and ad storage are both off until Accept. This site also withholds gtag('event', …) until Accept, so a denied visit produces no collect hit. The Try it buttons still show the push, then stop at the consent check.

A granted event becomes a request to https://www.google-analytics.com/g/collect. The query string, and the body when several events are batched, carry these fields.

en
Event name. page_view, click, scroll, and the other names in the schema below.
tid
Measurement id of this property. On this site that is G-JDE6BF33RY.
cid
Client id. After consent, Google stores it in the _ga cookie so later hits can be tied to the same browser.
sid
Session id for the current visit.
gcs
Consent state. The value starts with G1, then one digit for ad storage and one for analytics storage. 1 is granted and 0 is denied. G101 means analytics is granted and ads are denied, which is this site after Accept. G100 means both are denied.
dl
Document location. The page URL the hit is about.
dt
Document title.
ep.*
Event parameters. ep.page_path, ep.percent_scrolled, ep.link_url, and the rest of the fields this site attached to the event.
up.*
User properties. up.segments is the comma-separated list set with the segment_update event.

Live pipeline

Consent denied

Each new command walks the same five steps. The payload under the row is the one for the highlighted step. With consent off, Try it ends at a blocked network step and nothing is sent.

Waiting for the next push. Use a Try it button, accept consent and move around the site, or scroll this page.

dataLayer inspector

Every push since this page loaded, newest first. That includes the consent default, the config entry with send_page_view false, and later events. Denied Try it rows were not pushed into the real queue, so gtag.js never saw them.

No pushes for this filter yet.

Decoded GA hits

Outgoing /g/collect requests, captured by wrapping sendBeacon, fetch, and XMLHttpRequest, with PerformanceObserver as a backup. The left side is the push. The right side is the decoded query. Highlighted keys are the ones described above.

No collect request. Consent is off, so Try it stops before a hit is sent.

Event schema

These are the events this site sends. Emails, names, and form values are never parameters. login and sign_up always use method password.

page_view

Every App Router navigation, once. The GA4 config sets send_page_view to false, so this is the only page_view.

page_location, page_path, page_title, page_referrer

click

A link, button, or control click. External links set outbound to true.

link_url, link_text, element_id, outbound

scroll

The first time this page crosses 25, 50, 75, or 90 percent.

percent_scrolled

consent_update

Measurement consent is on. A denial does not push an event.

analytics_granted

login

A password sign-in succeeds.

method

sign_up

A password account is created.

method

logout

The visitor signs out.

none

generate_lead

The contact form stores a message. The payload has no name, email, or message text.

form_name

view_item

A blog post page is viewed.

content_type, item_id

select_content

A recommended-next card is clicked.

content_type, item_id, recommendation_reason

segment_update

The on-segments for this browser change. The same list is set as the user property segments.

segments

personalization_exposure

The personalized rules currently changing this page change.

personalization_rule

Why these picks

Reading path transitions…