Custom events are where GA4 becomes yours. Recommended events cover purchases and leads; custom events cover the calculator on your pricing page, the chat widget, the configurator step, the video that matters. Done well, they answer specific business questions. Done badly, they fill the property with click and button events nobody can interpret and parameters nobody can report on.
This guide covers naming, the dataLayer and GTM setup, registering dimensions and metrics, user properties, limits and verification.
Design Before You Build
Write a short table before touching GTM. For each event: name, what triggers it, parameters, and the question it answers.
| Event | Trigger | Parameters | Question |
|---|---|---|---|
| calculator_complete | Quote calculator finishes | calculator_type, estimated_value | Which calculator leads to quotes? |
| chat_started | Visitor opens chat and sends a message | page_section | Where do people need help? |
| phone_click | tel: link clicked | phone_location | Which pages drive calls? |
| video_milestone | 25, 50, 75, 100 percent | video_title, milestone | Which videos get watched? |
If you cannot write the question, do not build the event.
Naming Rules
- snake_case, lowercase, letters, numbers and underscores only.
- Start with a letter. Up to 40 characters.
- Describe the action, not the element:
quote_submitted, notgreen_button_click. - Do not use names reserved by Google, such as those starting with
google_,ga_orfirebase_, and do not reuse automatic event names. - Parameter names follow the same rules. Values are strings up to 100 characters or numbers.
Step 1: Push the Event to the dataLayer
Every custom event starts as a push from the site:
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'calculator_complete',
calculator_type: 'roof_replacement',
estimated_value: 18500,
calculator_steps: 4
});
Where the site cannot push directly, GTM can build the event from a trigger: a click on a specific element, element visibility, or a form success event. The GTM Triggers guide on this site covers those. Still push a named dataLayer event from the listener tag rather than firing GA4 straight from a click trigger, so the event has a clean name and parameters.
Step 2: Variables and Trigger in GTM
Create a Data Layer Variable for each parameter: calculator_type, estimated_value, calculator_steps. Create a Custom Event trigger with the event name calculator_complete.
Step 3: The GA4 Event Tag
Create a GA4 Event tag:
- Event name:
calculator_complete - Event parameters:
calculator_typemapped to its variable,estimated_valueto its variable,calculator_stepsto its variable. - Trigger: the custom event trigger.
If a parameter should ride on every event, set it in the Google tag's shared event settings instead of on each event tag.
Step 4: Register Custom Dimensions and Metrics
In GA4 Admin, then Custom definitions:
- Custom dimension, event scope, name "Calculator type", event parameter
calculator_type. - Custom metric, event scope, name "Estimated value", event parameter
estimated_value, unit currency or standard. - Custom dimension, event scope, name "Calculator steps", parameter
calculator_steps.
From the moment you save, reports can use them. Give them readable display names; the parameter name stays technical.
Step 5: User Properties
For attributes of the person rather than the event, send user properties. Push them to the dataLayer when known, for example on login:
window.dataLayer.push({
event: 'user_data_ready',
user_plan: 'pro',
user_customer_status: 'existing',
user_id: '48213'
});
In the Google tag's configuration, map user properties: plan to {{dlv - user_plan}}, customer_status to {{dlv - user_customer_status}}. Set User ID in the Google tag fields to {{dlv - user_id}} for cross-device reporting where you have logged-in users. Register each user property as a user-scoped custom dimension.
Never send personally identifiable information such as names, emails or addresses as parameters or user properties.
Step 6: Mark Key Events
If the custom event is a business outcome, open Admin, then Events, and mark it as a key event. If it should carry value, send value and currency as parameters.
Step 7: Verify
- GTM Preview. Trigger the event. Confirm the GA4 tag fires with all parameters populated.
- GA4 DebugView. Click the event and confirm each parameter and user property is present with the right value.
- The next day, open Reports, then Engagement, then Events, click the event, and add a secondary dimension using your custom dimension. If it appears, registration worked.
- Build an Exploration with the custom dimension and metric to be sure both are usable.
Limits to Remember
| Item | Standard property limit |
|---|---|
| Event-scoped custom dimensions | 50 |
| User-scoped custom dimensions | 25 |
| Item-scoped custom dimensions | 10 |
| Custom metrics | 50 |
| Parameters per event | 25 |
| Parameter name length | 40 characters |
| Parameter value length | 100 characters |
| User properties | 25 |
| Distinct event names | 500 per app instance; web is not hard-capped but keep it sane |
If you are near the dimension limit, consolidate. A cta_location parameter beats ten separate cta_header, cta_footer events.
Common Mistakes
- Parameters sent but never registered.
- Registering a dimension and expecting last month's data to appear.
- One event name per button, producing hundreds of events.
- Mixed case or hyphens in names, which GA4 treats as different events.
- Sending email addresses or names in parameters.
- Creating events in the GA4 interface and forgetting they exist.
Outcome
A small set of well-named custom events with registered dimensions and metrics, user properties for the attributes that matter, and reports that can finally answer the questions you built the events for.
