GA4 Event Tracking: Complete Guide to Custom Events & Parameters
GA4 Event Tracking: Complete Guide to Custom Events & Parameters
GA4's event-based data model is fundamentally different from Universal Analytics. Every user interaction is an event. Every page view is an event. Every conversion is an event. Understanding how to create, configure, and analyze custom events is the foundation of meaningful GA4 analytics.
This guide covers everything from GA4's event hierarchy to advanced custom event implementation using Google Tag Manager and the data layer. You will learn how to track every meaningful user interaction, attach custom parameters, create event-scoped dimensions, and build actionable reports from your event data.
Why This Matters: Out of the box, GA4 automatically tracks basic interactions (page views, scrolls, outbound clicks). But the events that actually matter to your business -- form submissions, video engagement milestones, product interactions, pricing page views -- require custom implementation. Without them, your GA4 reports tell you nothing actionable.
Table of Contents
- GA4 Event Model Explained
- Automatically Collected vs Custom Events
- Planning Your Event Taxonomy
- Implementing Events via GTM
- The Data Layer Deep Dive
- Custom Parameters and Dimensions
- E-Commerce Event Implementation
- Event Debugging and Validation
- Building Reports from Events
- FAQ
GA4 Event Model Explained
The Event Hierarchy
GA4 events fall into four categories, each with different implementation requirements:
| Event Type | Examples | Implementation | Customizable |
|---|---|---|---|
| Automatically collected | first_visit, session_start, user_engagement | None required | No |
| Enhanced measurement | page_view, scroll, click (outbound), file_download, video_start | Toggle on/off in GA4 Admin | Limited |
| Recommended events | login, sign_up, purchase, add_to_cart, generate_lead | Manual implementation | Parameters customizable |
| Custom events | pricing_page_view, demo_request, calculator_use | Manual implementation | Fully customizable |
Key rule: Always use recommended event names when they match your use case. GA4's machine learning features, audience building, and reporting are optimized for recommended events. Only create fully custom events for interactions that have no recommended equivalent.
Event Structure
Every GA4 event consists of:
- Event name (required): The action being tracked (e.g.,
generate_lead) - Parameters (optional): Key-value pairs providing context (e.g.,
form_name: 'contact') - User properties (optional): Attributes about the user (e.g.,
membership_tier: 'premium')
// Anatomy of a GA4 event
gtag('event', 'generate_lead', { // Event name
'form_name': 'contact_page', // Custom parameter
'form_type': 'demo_request', // Custom parameter
'value': 50, // Recommended parameter
'currency': 'USD' // Recommended parameter
});
Automatically Collected vs Custom Events
What GA4 Tracks Automatically
Before building custom events, understand what GA4 already captures so you avoid duplicating data.
Enhanced Measurement events (enabled by default):
| Event | Trigger | Key Parameters |
|---|---|---|
page_view | Every page load | page_location, page_referrer, page_title |
scroll | User scrolls 90% of page | percent_scrolled (always 90) |
click | Outbound link clicks | link_url, link_domain, outbound |
view_search_results | Site search used | search_term |
file_download | File link clicked | file_name, file_extension, link_url |
video_start | YouTube video starts | video_title, video_url, video_provider |
video_progress | YouTube video 10/25/50/75% | video_percent, video_title |
video_complete | YouTube video ends | video_title, video_url |
form_start | User begins form | form_id, form_name, form_destination |
form_submit | Form submitted | form_id, form_name, form_destination |
Limitation: Enhanced measurement form tracking uses generic detection that does not capture form field values or distinguish between different form types. For meaningful form analytics, you need custom events.
When to Create Custom Events
Create custom events when:
- You need to track an interaction not covered by automatic or enhanced measurement
- You need parameters beyond what enhanced measurement provides
- You need to differentiate between similar interactions (e.g., different form types)
- You want to track business-specific metrics (calculator usage, configurator steps)
Planning Your Event Taxonomy
Naming Conventions
GA4 event names must follow these rules:
- Maximum 40 characters
- Start with a letter
- Contain only letters, numbers, and underscores
- Case-sensitive (
Sign_Upandsign_upare different events) - Maximum 500 distinct event names per property
Best practice naming pattern:
[object]_[action]
Examples:
form_submit
video_play
product_view
calculator_complete
pricing_click
demo_request
newsletter_signup
chat_open
Event Planning Worksheet
Before implementation, map your key user interactions to events:
Business Goal: Increase demo requests
├── Event: demo_form_view
│ └── Parameters: page_location, traffic_source
├── Event: demo_form_start
│ └── Parameters: form_step, company_size_selected
├── Event: demo_form_submit (mark as conversion)
│ └── Parameters: company_size, industry, contact_method
└── Event: demo_scheduled
└── Parameters: meeting_date, sales_rep_assigned
This approach ties every event directly to a business outcome and ensures you collect the parameters needed for analysis.
For a complete GA4 property setup before implementing events, see our GA4 Setup Complete Guide.
Implementing Events via GTM↗
Basic Custom Event Tag
The most common pattern is firing a GA4 event from a GTM trigger:
Step 1: Create the trigger
In GTM, create a trigger for the user interaction you want to track. Common trigger types:
- Click trigger (for button clicks)
- Form submission trigger (for form completions)
- Custom event trigger (for data layer pushes)
- Scroll depth trigger (for engagement tracking)
- Timer trigger (for time-on-page milestones)
Step 2: Create the GA4 Event tag
Tag Type: [Google Analytics](https://developers.google.com/analytics): GA4 Event
Configuration Tag: Your GA4 Configuration tag
Event Name: generate_lead
Event Parameters:
form_name: {{Form Name Variable}}
form_type: demo_request
page_section: {{Click Element Section}}
Trigger: Demo Form Submit Trigger
Step 3: Configure the GA4 Event tag in JSON-like structure:
// GTM Custom HTML tag (alternative approach for complex events)
Advanced: Trigger Groups
For tracking multi-step user journeys, use GTM's trigger groups to fire an event only when multiple conditions are met:
Trigger Group: Engaged Prospect
Conditions (ALL must be met):
├── Viewed pricing page (Custom Event: pricing_page_view)
├── Spent 60+ seconds on site (Timer Trigger: 60000ms)
└── Scrolled 50%+ on any page (Scroll Trigger: 50%)
→ Fires Event: engaged_prospect
→ Parameters: pages_viewed, time_on_site, scroll_depth
The Data Layer Deep Dive
What Is the Data Layer?
The data layer is a JavaScript array that acts as a communication bridge between your website and GTM. It is the proper way to pass dynamic information from your site to tracking tags.
// The data layer is a simple JavaScript array
window.dataLayer = window.dataLayer || [];
// Push data to it from anywhere in your code
window.dataLayer.push({
'event': 'product_view',
'product_name': 'Enterprise Plan',
'product_category': 'Subscriptions',
'product_price': 299.00,
'currency': 'USD'
});
Data Layer Best Practices
// 1. Initialize data layer BEFORE GTM loads
// Place this in <head> before your GTM script
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'page_type': 'product',
'user_status': 'logged_in',
'user_tier': 'premium'
});
// 2. Use consistent key names across all pushes
// BAD: mixing naming conventions
dataLayer.push({ 'productName': 'Plan A' }); // camelCase
dataLayer.push({ 'product-name': 'Plan B' }); // kebab-case
dataLayer.push({ 'product_name': 'Plan C' }); // snake_case
// GOOD: consistent snake_case (matches GA4 convention)
dataLayer.push({ 'product_name': 'Plan A' });
dataLayer.push({ 'product_name': 'Plan B' });
// 3. Include event key to trigger GTM tags
// BAD: pushing data without an event (tag won't fire)
dataLayer.push({ 'form_name': 'contact' });
// GOOD: include event to trigger the corresponding tag
dataLayer.push({
'event': 'form_submit',
'form_name': 'contact'
});
// 4. Clear e-commerce objects before pushing new ones
dataLayer.push({ ecommerce: null }); // Clear previous
dataLayer.push({
'event': 'view_item',
'ecommerce': {
'items': [{
'item_id': 'SKU_123',
'item_name': 'Tracking Audit Kit',
'price': 49.99
}]
}
});
Dynamic Data Layer for SPAs
Single-page applications (React, Next.js, Vue) require special handling because page navigation does not trigger a full page load:
// Next.js / React Router: Push data layer on route change
import { useEffect } from 'react';
import { useRouter } from 'next/router';
function useDataLayerPageView() {
const router = useRouter();
useEffect(() => {
const handleRouteChange = (url) => {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'event': 'virtual_page_view',
'page_location': url,
'page_title': document.title
});
};
router.events.on('routeChangeComplete', handleRouteChange);
return () => {
router.events.off('routeChangeComplete', handleRouteChange);
};
}, [router.events]);
}
Custom Parameters and Dimensions
Registering Custom Dimensions
GA4 event parameters are not available in reports until you register them as custom dimensions:
- Go to GA4 Admin > Custom definitions > Custom dimensions
- Click "Create custom dimension"
- Configure:
- Dimension name:
Form Name - Scope:
Event - Event parameter:
form_name
- Dimension name:
Dimension limits:
| Scope | Free Properties | GA4 360 |
|---|---|---|
| Event-scoped | 50 custom dimensions | 125 |
| User-scoped | 25 custom dimensions | 100 |
| Item-scoped | 10 custom dimensions | 25 |
| Custom metrics | 50 | 125 |
Parameter Design Strategy
Design parameters to answer specific analytical questions:
// Event: generate_lead
// Question: Which form types generate the highest quality leads?
dataLayer.push({
'event': 'generate_lead',
'form_name': 'contact_page_form', // Which form?
'form_type': 'demo_request', // What kind of lead?
'lead_source': 'organic_search', // How did they find us?
'page_section': 'hero_cta', // Where on the page?
'company_size': '51-200', // Lead qualification
'value': 100, // Estimated lead value
'currency': 'USD'
});
For understanding how these parameters feed into conversion measurement, see our Conversion Tracking Complete Guide.
E-Commerce Event Implementation
GA4 E-Commerce Events Sequence
GA4 has a specific set of recommended e-commerce events that must be implemented in order:
E-Commerce Event Flow:
view_item_list → select_item → view_item → add_to_cart →
view_cart → begin_checkout → add_shipping_info →
add_payment_info → purchase
Purchase Event Implementation
The purchase event is the most critical e-commerce event. Here is a complete implementation:
// Clear previous ecommerce data
dataLayer.push({ ecommerce: null });
// Push purchase event
dataLayer.push({
'event': 'purchase',
'ecommerce': {
'transaction_id': 'TXN_20260309_001',
'value': 149.97,
'tax': 12.00,
'shipping': 5.99,
'currency': 'USD',
'coupon': 'SPRING20',
'items': [
{
'item_id': 'SKU_001',
'item_name': 'Tracking Audit Template',
'affiliation': 'RedClaw Store',
'coupon': 'SPRING20',
'discount': 10.00,
'item_brand': 'RedClaw',
'item_category': 'Templates',
'item_category2': 'Analytics',
'item_variant': 'Premium',
'price': 49.99,
'quantity': 3
}
]
}
});
Revenue Tracking Validation
Common mistakes that break revenue tracking:
// BAD: value as string
'value': '149.97' // String, not counted as revenue
// GOOD: value as number
'value': 149.97 // Number, correctly counted
// BAD: missing currency
'value': 149.97 // Without currency, GA4 may misinterpret
// GOOD: always include currency
'value': 149.97,
'currency': 'USD'
// BAD: transaction_id missing (causes duplicate counting)
'event': 'purchase',
'ecommerce': { 'value': 149.97 }
// GOOD: always include unique transaction_id
'event': 'purchase',
'ecommerce': {
'transaction_id': 'unique_order_id_here',
'value': 149.97,
'currency': 'USD'
}
Event Debugging and Validation
GA4 DebugView
Enable DebugView in GA4 to see events in real-time as they fire:
- Install the Google Analytics Debugger Chrome extension
- Enable it and navigate to your site
- In GA4, go to Admin > DebugView
- Your device appears with real-time event stream
GTM Preview Mode Validation
GTM's Preview mode shows:
- Which tags fired on each interaction
- What data was available in the data layer
- Whether triggers matched correctly
- What values were sent to GA4
Automated Validation Script
// Drop this in your browser console to validate GA4 events
(function validateGA4Events() {
const originalPush = window.dataLayer.push;
window.dataLayer.push = function() {
const args = arguments[0];
if (args && args.event) {
console.group(`GA4 Event: ${args.event}`);
console.log('Parameters:', JSON.stringify(args, null, 2));
// Validate common issues
if (args.event === 'purchase') {
if (!args.ecommerce?.transaction_id) {
console.error('MISSING: transaction_id (will cause duplicates)');
}
if (typeof args.ecommerce?.value !== 'number') {
console.error('ISSUE: value should be a number, got:', typeof args.ecommerce?.value);
}
if (!args.ecommerce?.currency) {
console.warn('WARNING: currency not set');
}
}
// Check event name conventions
if (args.event !== args.event.toLowerCase()) {
console.warn('WARNING: Event name should be lowercase');
}
if (args.event.includes('-')) {
console.warn('WARNING: Use underscores, not hyphens in event names');
}
console.groupEnd();
}
return originalPush.apply(this, arguments);
};
console.log('GA4 Event Validator: Active');
})();
For tracking UTM↗ parameters alongside custom events, see our UTM Parameters Usage Guide.
Building Reports from Events
Explorations for Custom Events
Use GA4 Explorations to build custom reports from your event data:
- Funnel Exploration: Map your custom events as funnel steps to visualize drop-off
- Free Form Exploration: Create pivot tables with event-scoped dimensions
- Path Exploration: See which events users trigger before converting
- Segment Overlap: Compare users who triggered specific events
Custom Event Dashboard Example
Create a dashboard answering key questions:
Dashboard: Lead Generation Performance
├── Card 1: Total generate_lead events (this week vs last week)
├── Card 2: Conversion rate by form_type (table)
├── Card 3: Lead value by traffic source (bar chart)
├── Card 4: Form completion funnel (form_start → form_submit)
└── Card 5: Top pages driving lead events (table)
For broader data analysis approaches, see our Ad Data Analysis for Beginners guide.
Need help implementing GA4 event tracking? RedClaw sets up comprehensive event tracking that captures every meaningful user interaction, from first click to final conversion. Get a free tracking audit
FAQ
How many custom events can I have in GA4?
GA4 allows up to 500 distinct event names per property, with up to 25 parameters per event and 50 custom dimensions for event-scoped data (free tier). In practice, most businesses need 20-40 custom events to cover all meaningful interactions. Focus on events tied to business outcomes rather than tracking every possible micro-interaction.
Should I implement events via GTM or hardcode them?
Use GTM for the vast majority of event tracking. GTM provides version control, preview/debug mode, consent management integration, and the ability to modify tracking without deploying code changes. Hardcode events only when GTM is unavailable (e.g., server-side events) or when you need guaranteed event firing (critical conversion events like purchases where GTM load failure would mean data loss).
What is the difference between event parameters and user properties?
Event parameters describe the specific interaction (what happened, where, what was involved). User properties describe the person (account tier, signup date, preferred language). Event parameters are scoped to a single event hit; user properties persist across all future events until changed. Use event parameters for action context and user properties for audience segmentation.
Why are my custom events not appearing in GA4 reports?
Custom event parameters must be registered as custom dimensions before they appear in standard reports. Go to Admin > Custom definitions > Create custom dimension, select "Event" scope, and enter the exact parameter name. It takes 24-48 hours for new dimensions to populate with data. Also verify events are actually firing using GA4 DebugView or GTM Preview mode.
How do I track single-page application (SPA) navigation in GA4?
GA4's enhanced measurement page_view event relies on the History API, which works for most SPAs using pushState navigation. However, it may miss soft navigations or hash-based routing. The most reliable approach is to push a custom virtual_page_view event to the data layer on every route change, including page_location, page_title, and any custom parameters. Then configure a GTM trigger on this custom event to fire a GA4 page_view tag.
Turn your GA4 data into actionable insights. Our analytics team configures event tracking that answers the questions your business actually needs answered. Check your ROAS
Related reading: GA4 Setup Complete Guide | Conversion Tracking Complete Guide | Pixel + CAPI Dual Tracking Setup | UTM Parameters Usage Guide | Ad Data Analysis for Beginners
Related Posts
Ad Data Analysis for Beginners 2026 | Essential Guide to Data Interpretation
Learn ad data analysis from scratch. Master core metrics like CTR, CPC, ROAS, and conversion tracking. Understand what the data means and make smarter advertising decisions with our comprehensive beginner's guide.
Reporting Automation Guide 2026 | Essential Efficiency Tips for Digital Marketers
Learn reporting automation to save 80% of data processing time. This guide covers Meta Ads, Google Analytics automation tools, and practical tutorials to build efficient data dashboards.
UTM Parameters Guide 2026: Track Every Campaign Click
Master UTM parameters for accurate campaign tracking. Naming conventions, GA4 attribution, URL builder tips, and common mistakes to avoid.