Tracking

How to Build a dataLayer for a Custom Website

By Hira Ads Pro·2 min read·October 12, 2026

A dataLayer is a JavaScript array that your website uses to tell Google Tag Manager what just happened. On custom-built sites it is the most reliable way to track leads, because the event fires from the code that knows the action really succeeded.

Why not just track clicks?

Click triggers fire when someone presses a button, whether or not the form was valid, the payment went through or the booking was saved. A dataLayer event pushed after the server confirms success measures the outcome, not the attempt.

The basic pattern

Initialise the dataLayer before the GTM snippet, then push events as they happen:

<script>
  window.dataLayer = window.dataLayer || [];
</script>
<!-- GTM container snippet here -->
window.dataLayer.push({
  event: 'generate_lead',
  form_name: 'quote_request',
  service: 'office_cleaning',
  event_id: 'lead_8f2c91'
});

Naming conventions

  • Use snake_case and keep names stable once in use
  • Prefer Google’s recommended names where they fit: generate_lead, sign_up, purchase
  • Keep parameters flat and predictable: form_name, service, value, currency
  • Never push personal data in plain text. If ads platforms need email or phone for matching, pass it to a hashing step or to the server

When to push

ActionPush when
Lead formThe server returns success (AJAX) or the thank-you page loads
BookingThe booking is saved, not when the calendar opens
PurchaseThe order confirmation is rendered, once per order ID
Phone or WhatsApp clickOn click, as a secondary action

For purchases, guard against duplicates when someone refreshes the confirmation page, for example by storing the order ID in session storage.

Add an event_id

If the same lead is also sent server-side (for Meta CAPI or Google enhanced conversions), include a unique event_id. The browser and server events share it so the platforms can deduplicate. See how Meta CAPI deduplication works.

Ecommerce example

window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
  event: 'purchase',
  ecommerce: {
    transaction_id: 'T12345',
    value: 249.00,
    currency: 'GBP',
    items: [{ item_id: 'SKU-1', item_name: 'Deep clean', price: 249.00, quantity: 1 }]
  }
});

Clearing ecommerce first stops values from a previous push leaking into the next one.

Write a spec your developer can follow

A one-page table with event name, when it fires, parameters and an example push saves weeks of back-and-forth. Include the page or component where each push lives.

Test it

  • Open the browser console and type dataLayer to see what was pushed
  • Use GTM Preview to confirm the event and its variables
  • Check GA4 DebugView and the ad platform’s test tools

Need a spec written for your build? This is part of conversion tracking setup.

Want this set up properly on your site?

Request an audit and get a clear plan before any changes are made.

Request an Audit →