dataLayer & Event Taxonomy Spec
version 1.0.0 · status stable · updated 2026-06-07
The dataLayer is the contract between the website and every downstream tool. When it is
inconsistent, every tag built on top inherits the mess. This is a portable spec you can adopt, fork,
and enforce — it ships as a machine-readable
JSON Schema so you can validate it the same way in three places:
in the browser with the free dataLayer Validator, in CI against your
fixtures, and at the edge before data is forwarded server-side.
Principles
- One object shape, snake_case everywhere. Event names match
^[a-z][a-z0-9_]{1,49}$. NocamelCase, no spaces, no per-developer dialects. - Context on every push.
page(anduser/consentwhere known) accompany every event so a tag never has to guess state. Set a base object on load; merge, don’t clobber. - No raw PII — ever. The schema actively rejects
user.email,user.phone, anduser.name. Hash client-side first (see the PII Hasher) or pass opaque IDs only. - Consent is data. Mirror the granted state (
ad_storage,analytics_storage,ad_user_data,ad_personalization) so server-side and Consent Mode v2 logic can read it deterministically. - Reset e-commerce. Push
{ ecommerce: null }before each e-commerce event to stop value bleed between products/transactions.
Canonical events
page_view, view_item_list, view_item, select_item, add_to_cart, remove_from_cart,
view_cart, begin_checkout, add_payment_info, add_shipping_info, purchase, refund,
generate_lead, sign_up, login, search, view_promotion, select_promotion. Conditional
requirements (e.g. purchase requires ecommerce.transaction_id, value, currency, items) are
encoded in the schema’s allOf/if-then rules, so the validator enforces them automatically.
Example: a conforming add_to_cart
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ ecommerce: null }); // reset
window.dataLayer.push({
event: 'add_to_cart',
page: { path: '/p/widget-pro', type: 'product', environment: 'production' },
consent: { analytics_storage: 'granted', ad_storage: 'denied' },
ecommerce: {
currency: 'USD',
value: 49.0,
items: [{ item_id: 'WP-1', item_name: 'Widget Pro', price: 49.0, quantity: 1 }]
}
});
Validating it
- Browser — paste the push (or load a live page) into the dataLayer Validator.
- CI —
ajv validate -s datalayer.schema.json -d "fixtures/*.json"(Ajv, draft 2020-12) on every PR that touches tracking. Fail the build on a schema violation; this is the cheapest tracking-QA you will ever ship. - Edge / server-side — validate against the same schema before forwarding events to your warehouse or server-side container, and route failures to a dead-letter queue instead of silently ingesting bad data.
Conformance
A dataLayer conforms if every push validates against the published schema for the declared
specVersion. A tool conforms if it validates against this schema (or a user-supplied superset),
reports the failing JSON Pointer path for each error, and never mutates the data it inspects.
Templates, validators, and the governance checklist.