GA4 Events and the dataLayer: How to Set Up Custom Measurement

04 AUGUST 20267 min readGoogle Analytics

GA4 Events and the dataLayer: How to Set Up Custom Measurement

As soon as GA4 is installed, it starts collecting a few dozen events. But the ones that really matter to your business — “form submitted”, “WhatsApp button pressed”, “pricing page viewed” — none of them come automatically. This post is about that part: how to set up your own events.

Short answer

Custom measurement has three steps: (1) the website writes information about the action into the dataLayer, (2) Google Tag Manager picks it up and sends it to GA4 as an event, (3) in GA4 the parameter is registered as a custom dimension and becomes a column in reports. Event names should be snake_case and come from a fixed dictionary.

If the setup isn’t finished yet, first read the GA4 setup post; if you have questions about the model — what GA4 is.

The 4 types of events

Colourful program code on a screen — dataLayer and event setup
Automatic events are the same for everyone. Your edge over competitors comes from the events you build yourself.

Level 1 — no work

Automatically collected

page_view, session_start, first_visit, user_engagement. They come as soon as the code is connected.

Level 2 — one switch

Enhanced measurement

scroll, click, file_download, form_start, form_submit, view_search_results, video events.

Level 3 — you set it up, the name is ready

Recommended

Google has defined the name and parameters in advance: generate_lead, purchase, add_to_cart, sign_up, search, share.

Level 4 — everything is yours

Custom

You give it a name yourself: whatsapp_click, price_calculator_used, brochure_view.

The rule is simple: look at the higher levels first. If there’s a recommended event that meets your need, don’t invent your own name — use Google’s.

Why should you use the recommended names?

Google “recognises” some event names in advance. If you use those names, GA4 and Google Ads treat them specially: ready-made report columns open up, e-commerce reports build themselves, and using them as conversions in Ads becomes easier.

GoalCorrect nameWrong variant
Lead / enquirygenerate_leadForm_submitted
PurchasepurchaseOrder-Complete
Add to cartadd_to_cartaddToCart
Sign-upsign_upregister_user
Site searchsearchSite_Search

Naming rules

  • Only lowercase letters and underscores: whatsapp_click. GA4 is case-sensitive — Purchase and purchase are two separate events.
  • No spaces, dashes or non-Latin/accented letters. Stick to plain a–z.
  • A verb + object structure: it should say what happened — form_submit, video_play.
  • Fewer events, more parameters. Instead of five separate events (form_seo, form_ads…), set up one generate_lead event with a form_name parameter.
  • Keep a dictionary. A simple spreadsheet: event name, when it fires, which parameters it has. Six months from now this document will be worth its weight in gold.
The most important rule

When you create an event name, there’s no way back: renaming an event later in GA4 doesn’t fix past data. So spend 10 minutes on day one to set up a written naming system.

Parameters and limits

The event says “what happened”; the parameters say “under what circumstances it happened”. The limits Google has defined are:

LimitFree GA4Analytics 360
Parameters per event2525
Event-scoped custom dimensions50125
User-scoped custom dimensions25100
Item-scoped custom dimensions1025
Custom metrics50125
Calculated metrics550

An important nuance: sending a parameter doesn’t make it visible in reports. The parameter reaches GA4, but for it to appear as a column in reports you have to register it as a custom dimension. It’s the technical misunderstanding I come across most often.

What is the dataLayer?

The dataLayer is the “mailbox” between the website and Google Tag Manager. The website drops information into it, and GTM reads from it. Neither knows the other’s code; there’s only this box in between.

Website

A form was submitted successfully

→

dataLayer.push

The event name and data are dropped into the box

→

GTM trigger

Sees the name “form_success” and fires the tag

→

GA4 event

generate_lead + parameters

The advantage of this structure: when the event needs to change, you touch only GTM, not the site’s code.

Practical example 1 — form submission

When a form is submitted successfully, the site’s code writes one line:

In the site’s code — after the form is submitted successfully
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  'event': 'form_success',        // the GTM trigger waits for this name
  'form_name': 'get_a_quote',      // which form
  'form_location': 'service_page',
  'service': 'meta_ads'            // which service was chosen
});

On the GTM side, three elements are set up:

  1. Trigger: Custom Event → event name form_success.
  2. Variables: a Data Layer Variable for each field — form_name, form_location, service.
  3. Tag: GA4 Event → event name generate_lead, with those variables as parameters.
GTM › Tags › GA4 — generate_lead

Tags

GA4 — Google Tag

GA4 — generate_lead

GA4 — whatsapp_click

Triggers

Variables

FieldValue

Tag typeGA4 Event

Event namegenerate_lead

Parameter form_name{{DLV - form_name}}

Parameter service{{DLV - service}}

TriggerCE - form_success

The {{DLV - form_name}} notation is GTM’s variable syntax: it means “take the form_name field from the dataLayer”.

Practical example 2 — WhatsApp and phone clicks

For this event you don’t even need to touch the site’s code — GTM can catch it on its own by looking at the link address.

GTM — trigger setup
// WhatsApp clicks
Trigger type: Click - Just Links
Condition:    Click URL  contains  wa.me

// Phone clicks
Trigger type: Click - Just Links
Condition:    Click URL  starts with  tel:

Then a GA4 Event tag: event name whatsapp_click, and send {{Click URL}} and {{Page Path}} as parameters — that way you’ll see how many clicks came from which page.

whatsapp_click ← a custom event: you name it yourself
page_path /en/services/meta-ads
click_url https://wa.me/994XXXXXXXXX
button_location floating_button

Why button_location? The same WhatsApp button appears in several places on a site. Without this parameter you’ll never know which one works.

Making a parameter visible in reports

Sending a parameter isn’t enough. To see it as a column in reports, you have to register it as a custom dimension:

1. The parameter is sent

The service parameter goes from the GTM tag

→

2. Registration

Admin → Custom definitions → Create custom dimension

→

3. A column in the report

Data starts to appear after 24–48 hours

It doesn’t work retroactively: a custom dimension only shows data from after it was registered. So register the parameter as soon as it’s set up.

When registering, the field name (Event parameter) must be exactly the same, letter for letter, as the name the parameter has in the code. This field can’t be changed later.

Marking an event as a key event

GA4 doesn’t know on its own which event matters to the business — you have to tell it. In the Admin → Events list, you turn on the “Mark as key event” switch next to the event. After that:

  • The event appears in a separate “Key events” column in every report.
  • Attribution reports compare channels based on exactly this event.
  • It can be passed to Google Ads as a conversion.

Note: the event must happen at least once before it appears in the list. For a new event, test it yourself first, then mark it.

Testing and 4 typical mistakes

Test every new event in the Admin → DebugView section: turn on GTM Preview mode, perform the action and check that the event appears together with its parameters.

MistakeSymptomFix
Capital letters in the event nameTwo similar events appear in the reportsnake_case everywhere
Parameter not registeredThe event is there, but the parameter column is emptyCustom definitions → create
Trigger set up too broadlyThe event also fires on clicks it shouldn’tNarrow the condition (Click URL, Page Path)
Measuring by the thank-you pageFor forms that don’t open a page, the event never arrivesMeasure with dataLayer.push
The value of a measurement system isn’t measured by the number of events but by the order in their names. 12 well-ordered events are far more useful than 60 messy ones.

Can events be set up without the dataLayer?

Yes. Events like clicks, pageviews and element visibility can be set up with GTM’s built-in triggers without touching the site’s code. The dataLayer is needed when what you’re measuring isn’t visible on the page — for example the order amount, the user type or an internal signal marking the moment a form was submitted successfully.

How many parameters can be sent with one event?

Google’s limit is 25 parameters per event. In practice it’s hard to reach — 3–6 parameters are enough for most events. The more important limit is custom dimensions: in free GA4, 50 at event level and 25 at user level.

Will old data appear when I register a custom dimension?

No. A custom dimension only shows data collected after it was registered — there’s no backfill. So you need to register the parameter as soon as you start sending it; saying “we’ll look at it later” means directly losing data.

Can I rename an event later?

GA4 has an option to rename events (Admin → Events → Modify event), but it only affects future data. Events collected under the old name stay under the old name and appear as two separate rows in reports. That’s why it matters to set up naming correctly from day one.

How many events should you set up?

5–8 events are enough to start: the lead form, WhatsApp click, phone click, views of key pages and file downloads. Every event should have a decision behind it — if you can’t answer “what will I do when I see this number?”, don’t set that event up.

How do you set up e-commerce measurement in GA4?

Google has a ready set of events for e-commerce: view_item, add_to_cart, begin_checkout, purchase. Product data is sent with each of them in the items array. When the names and structure are followed exactly, GA4’s e-commerce reports switch on by themselves — nothing else needs to be set up.

The event shows in DebugView, but the parameter is empty — why?

There are two possibilities. First: the GTM variable (Data Layer Variable) is set up with the wrong name — it must match the name in the dataLayer letter for letter. Second: the dataLayer.push fires after the tag, so at the moment the tag runs, the data isn’t in the box yet. The first is far more common.

Conclusion

Automatic events are the same for everyone — they don’t give you an edge. Your difference from competitors comes from the events you build yourself: which button was pressed, which form worked, which service people showed interest in. Set them up with well-ordered names and the right parameters, and the GA4 report becomes a place where you ask questions, not where you guess.

The next step is learning to read this data: GA4 reports and Explorations. If you’d like me to build the measurement system for your website — the analytics and tracking page or the get a quote form.

Source: Google official documentation — about events, creating custom dimensions, custom dimension limits, key events.

Share

Namig Pashayev

Digital marketing specialist. Works on advertising, analytics and tracking, and writes here about what he sees in practice.

Need help with this topic?

Tell us what you need. We'll review your ad accounts and website and send a written proposal within 5 business days. The audit is free.