Data layer
Your data layer,
read as it is.
No rebuild for a tracking tool. The tag reads the GA4, Universal Analytics and gtag pushes your store already makes, finds customer data in the shapes plugins actually write, and cbq() sends anything else in one line.
30-day free trialNo card requiredSet up in minutes
Do I have to rebuild my data layer for this?
My plugin writes customer data its own way. Will it be read?
GA4
dataLayer.push({ event: 'add_to_cart',
ecommerce: { items: [{ item_id: 'NW-150', price: 349 }] } })Universal Analytics
dataLayer.push({ event: 'addToCart',
ecommerce: { add: { products: [{ id: 'NW-150', price: '349' }] } } })gtag
gtag('event', 'add_to_cart',
{ items: [{ item_id: 'NW-150', price: 349 }] })What Cookiebees receives, from all three
How do I send an event that is not a standard one?
Is there a Tag Manager template?
What it is worth
Less developer time, better matches
No developer sprint to install
If your store already pushes GA4 ecommerce events, switch the listener on and the tag reads them as they are.
Customer data you already have, used
Enhanced conversion objects, Meta’s short names, GTM4WP keys: all read into one user_data.
Better matches on later events
Customer data given once is kept on the visitor, so a purchase on another page or another day still carries it.
Read as written
Three dialects and a dozen customer-data shapes, read as one.
The tag listens to every dataLayer push, including the ones made before it loaded. It reads GA4 ecommerce, Universal Analytics Enhanced Ecommerce and gtag calls the same way, and looks for customer data on the purchase, the checkout steps and every earlier push on the page.
- Thirteen GA4 shop events, and purchase when you switch it on
- tax, shipping, discount, payment_type and shipping_tier stored on the order
- cod and cash on delivery recognised as cash on delivery
- Any other key on a push is kept with the event as a custom parameter
What your plugin pushed
dataLayer.push({ customerBillingEmail: 'buyer@example.com',
customerBillingPhone: '+91 90000 00000',
customerBillingCity: 'Lucknow', customerBillingPostcode: '226001' })
dataLayer.push({ event: 'purchase', ecommerce: {
transaction_id: '10482', value: 2340, tax: 357,
shipping: 0, payment_type: 'cod', items: [ … ] } })What the tag read
cbq() and the template
When your data layer speaks its own language, map it in one call.
cbq('event', name, params) sends any event, standard or your own, from a Custom HTML tag or your own code. cbq('set', 'user_data', ...) gives customer data once for every later event on the page. The Cookiebees Tag Manager template does the same without code, and is published on GitHub to import.
- Calls made before the tag loads wait in a queue and go out in order
- Flat parameters or GA4’s ecommerce object, both read
- A copy of a data layer event sent within 3 seconds is dropped
- The tag goes in the page head, above Tag Manager; the template only sends events to it
The one line that keeps early calls
window.cbq = window.cbq || function(){ (cbq.q = cbq.q || []).push(arguments); };cbq('set', 'user_data', { email, phone })
queued · the tag has not loaded yet
cbq('event', 'quiz_completed', { result: 'dry skin' })
queued
quiz_completed leaves from your tracking address, with the customer data, attribution and visitor id attached.
Remembered by the server
Customer data given once travels with every later event.
Customer data on any event, a purchase or not, is kept against the visitor on our server, filled forward and never blanked. Every later event from that browser goes to Meta and Google with it, even on another page, another day, or when the data layer no longer has it. It is hashed before it leaves.
- Email, phone, name, street, city, region, postal code, country, external id
- Already-hashed SHA-256 values are kept as hashes
- A value the event itself carries wins over one set earlier
- Nothing is written or sent while your consent banner says no
What came in
the shopper typed it
phone
from checkout
address
city, zip, country
click id
captured on landing
What we sent
em
a1f4…9c02
ph
7be1…44d8
ct / zp / country
3d90…b7e1
fbc / gclid
passed through raw
external_id
stable per customer
Match quality
0/10
Data layer & GTM template, on your own site.
Start a workspace and watch it work on your next order or lead, or let us walk you through it.
Inside the module
What is inside
The full specification is a knowledge base page you can hand to a developer.
The listener
Reads every dataLayer push, GA4, Universal Analytics and gtag, with one switch for purchase
Customer data shapes
user_data, Google’s enhanced conversions, Meta’s short names, billing and shipping objects, plugin keys
cbq()
Send any event, or set customer data once for the page, with a queue for early calls
Tag Manager template
One tag per event, fields to map, and a mode that only sets customer data
Duplicate guard
The same event from two ways within 3 seconds is counted once
Visitor profiles
Customer data kept on the visitor and used by every later send
Open the browser's Network tab, filter to event, and read the payload: every customer field your data layer carried is in user_data.
Where this sits
One of the four steps an order goes through.
Every feature reads the same identity. Open any of them; each has its own page.
1Capture
Every visit, on your own domain.
2Understand
First click to delivered order.
3Send back
Real revenue back to the ads.
4Act
Turn it into the next sale.
Install on the data layer you have
No rebuild.Every field read.
Paste the tag in the page head, above Tag Manager. Your existing pushes start arriving, and cbq() covers the rest.