Cookiebees
1Capture: Every visit, on your own domain

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?

Three stores · one add to cartthree dialects

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

eventadd_to_cartitem_idNW-150price349
Whichever way your store writes it, the event that arrives is the same, with the same item fields.

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
Thank-you page · dataLayerreading

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

emailbuyer@example.com
phone+91 90000 00000
cityLucknow
postal_code226001
tax357
payment_typecash on delivery
Capital letters, underscores and hyphens do not matter: customerBillingEmail and customer_billing_email are the same key.

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
Your page · two calls, before and after the tag0 in queue

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

The Cookiebees tag loads in the page head

quiz_completed leaves from your tracking address, with the customer data, attribution and visitor id attached.

Calls made before the tag loads wait in the queue and go out in order. No tag sequencing in Tag Manager.

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
Event stream · purchase payload

What came in

email

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

Nothing leaves as plain text. Every identifier is SHA-256 hashed first.

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.

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.