Google Analytics 4 collects some data automatically: page views, session starts, first visits, and a handful of engagement signals. For many organizations, that out-of-the-box tracking covers maybe 20% of the behavioral data they actually need to make decisions. The other 80% requires custom events.

Custom events are how you track the things that matter to your specific business: a pricing page visit that leads to a demo request, a product filter that correlates with purchase intent, a video that users who convert are more likely to watch, or a form field where prospects consistently drop off. None of this is captured automatically. All of it is buildable with GA4 and Google Tag Manager.

This guide covers how custom event tracking actually works, how to design an event schema that stays useful over time, and how to build it in GTM without creating a maintenance problem for your future self.

How GA4 Events Actually Work

In Universal Analytics, the old Google Analytics, hits were categorized by type: page views, events, transactions, social hits. Each type had its own structure and its own reporting columns. GA4 abandoned this entirely. Everything in GA4 is an event. A page view is an event. A purchase is an event. A button click you decide to track is an event. They all follow the same structure.

Every GA4 event has a name and can have up to 25 parameters attached to it. Parameters are the contextual details: what page the event happened on, what product was involved, what the user's account type is, what the value of the action was. The event name tells you what happened. The parameters tell you the specifics.

This structure is more flexible than Universal Analytics was, but it also requires more intentional design. In UA, you could throw any combination of category, action, and label at an event and it would land somewhere in your reports. In GA4, if you do not define parameters in advance and register them as custom dimensions, they do not show up in the interface at all. The data is collected but invisible until you surface it.

Designing Your Event Schema Before You Build

The most common GA4 implementation mistake is building events reactively, one at a time, as someone asks for them. After a year of this, you end up with 60 custom events with inconsistent naming, duplicate coverage, and parameters that mean different things on different events. The data is technically there but practically unusable.

Before writing a single tag in GTM, spend time on your measurement plan. A measurement plan is a document that defines every event you intend to track, what triggers it, what parameters it carries, and what business question it answers. It does not need to be elaborate, but it needs to exist.

Event Naming Conventions

GA4 event names are case-sensitive, cannot contain spaces, and should follow the snake_case convention that Google uses for its own automatic events. Beyond the technical requirements, consistency matters enormously. A naming convention to follow:

  • Use a verb-noun structure: view_item, select_content, submit_form
  • Be specific enough to be meaningful without being so specific that the name only applies to one context: submit_contact_form rather than click_contact_page_submit_button_v2
  • Reserve prefixes for categories if your event library will be large: ecom_add_to_cart, content_video_start, nav_filter_apply
  • Never use spaces, hyphens, or capital letters

Parameter Design

Parameters are where the analytical value lives. An event called submit_form tells you that a form was submitted. Add a parameter called form_name and you know which form. Add form_location and you know where on the site it appeared. Add user_type and you can segment by whether the submitter was a new or returning visitor.

A few parameter design principles:

  • Parameters should answer the most likely follow-up questions about the event. Think about how you will filter and segment in GA4 reports before you decide what to collect.
  • Keep parameter names consistent across events where they cover the same concept. If you call it product_id on your add-to-cart event, call it product_id on your purchase event too. Inconsistent naming makes cross-event analysis much harder.
  • GA4 limits you to 25 parameters per event and 50 custom dimensions per property. Do not waste these slots on data you will not actually analyze.

The dataLayer: Why It Matters and How to Use It

The dataLayer is a JavaScript object that lives on your page and acts as a communication channel between your website and Google Tag Manager. It is how you pass dynamic data, like product names and prices and user IDs, from your website into your tags without writing messy custom JavaScript inside GTM.

For simple click tracking, you can get by without a dataLayer. GTM has built-in variables for things like click text, click URL, and form IDs that require no additional setup. But for anything that involves data your website knows that GTM cannot simply read from the DOM, like a transaction ID, a user's account tier, or the contents of a shopping cart, you need the dataLayer.

A dataLayer push for a purchase event looks like this:

dataLayer Push — Purchase Event
// Fired by your website on the order confirmation page
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  'event': 'purchase',
  'ecommerce': {
    'transaction_id': 'ORD-20240315-8821',
    'value': 129.00,
    'currency': 'USD',
    'items': [{
      'item_id': 'SKU-4492',
      'item_name': 'Product Name',
      'price': 129.00,
      'quantity': 1
    }]
  }
});

GTM picks this up through a custom event trigger that listens for the event name, and variables that read values from the dataLayer object. Your GA4 event tag then maps those variables to GA4 event parameters.

The dataLayer needs to be pushed by your development team, or by code on your site. This is the part that requires collaboration between analytics and engineering. Developers need a clear specification for what data to push, in what format, and at what point in the page lifecycle. A well-written dataLayer specification is one of the most valuable documents an analytics team can produce.

Building Custom Events in GTM: Step by Step

Once your measurement plan is defined and your dataLayer is being populated by the website, the GTM side of a custom event consists of three components: a trigger, variables, and a tag.

Triggers

The trigger defines when the tag fires. For events based on dataLayer pushes, you use a custom event trigger that matches the event name. For click-based tracking, you use click triggers filtered to the specific element. For scroll depth, form submissions, and other interactions, GTM has built-in trigger types that cover most scenarios.

Trigger specificity matters. A click trigger that fires on all clicks will create noise. A click trigger filtered to a specific CSS class or element ID fires only when it should. Write your trigger conditions to be as specific as the event requires, and test them in GTM preview mode before publishing.

Variables

Variables are how GTM captures dynamic values. For dataLayer-based events, you create dataLayer variables that point to specific paths in the dataLayer object. For the purchase event above, you would create variables like:

  • DL — Transaction ID pointing to ecommerce.transaction_id
  • DL — Purchase Value pointing to ecommerce.value
  • DL — Currency pointing to ecommerce.currency

For click-based events, built-in variables like Click Text, Click URL, and Click Classes often give you what you need without additional configuration. Enable them in the Variables section of GTM before you try to use them in tags.

The GA4 Event Tag

The tag is the GTM component that actually sends data to GA4. Choose the Google Analytics: GA4 Event tag type, point it at your GA4 configuration tag, give it the event name from your measurement plan, and map your variables to event parameters.

One thing to get right: the parameter names you enter in the GTM tag must exactly match the parameter names you plan to register as custom dimensions in GA4. If you call it form_name in GTM and try to create a custom dimension called formName in GA4, they will not connect.

Registering Custom Dimensions in GA4

Collecting parameters in an event is only half of the work. To see those parameters in GA4 reports, you need to register them as custom dimensions in the GA4 property settings. Go to Admin, then Custom Definitions, then Custom Dimensions. Create a dimension for each parameter you want to report on, using the exact same parameter name you used in GTM.

GA4 distinguishes between event-scoped and user-scoped dimensions. Event-scoped dimensions are tied to a specific event: a product name parameter on a purchase event is event-scoped. User-scoped dimensions are properties of the user that persist across sessions: account type, subscription plan, loyalty tier. Use the correct scope or your dimension data will not aggregate the way you expect.

Important: GA4 does not backfill custom dimension data. Registering a dimension today will not populate historical data from events that already fired. This is another reason to register dimensions before you deploy events, not after.

Custom Events Worth Building for Most Sites

Every site is different, but a few custom events come up in nearly every engagement we do at TestedPath:

form_start — Form Engagement

Fires when a user first interacts with a form field, before submission. Combined with your form submission event, this tells you what percentage of users who start forms complete them, and which forms have the highest abandonment rates.

video_progress — Video Engagement

Fires at 25%, 50%, 75%, and 100% of video completion. The built-in GA4 video tracking covers YouTube embeds, but most hosted video players require a custom implementation. Knowing that users who reach 75% of your product demo video convert at 3x the rate of users who do not is actionable data.

search_performed — Site Search

GA4 has some built-in search tracking, but it is limited to URL-parameter-based search. If your search results are loaded dynamically without a URL change, you need a custom event. Include the search term and result count as parameters. Zero-result searches deserve particular attention.

error_encountered — Front-End Errors

Tracks JavaScript errors, form validation failures, and API error responses visible to the user. Most teams do not track errors in analytics, which means they have no visibility into how often visitors hit broken experiences. This event, filtered to high-frequency errors, can surface UX problems that support tickets never catch.

content_engagement — Scroll and Reading

Beyond GA4's built-in scroll depth event (which only fires at 90%), a custom scroll event can track meaningful engagement thresholds relevant to your content: 25%, 50%, 75%. Include the page section or content category as a parameter to understand which topics drive the deepest reading.

Testing Before You Publish

GTM preview mode is your primary testing tool, and it should be used before every publish. Preview mode shows you every tag that fired on a given page interaction, the trigger that caused it to fire, and the variable values it captured. If a tag fired when it should not have, or did not fire when it should, preview mode tells you why.

For GA4-specific validation, GA4's own DebugView is indispensable. Enable debug mode by adding ?gtm_debug=x to your URL while in GTM preview mode, and then open DebugView in your GA4 property. You will see events arriving in real time with all their parameters, which lets you confirm that what GTM is sending is what GA4 is receiving.

Test every trigger condition explicitly. If your trigger is supposed to fire on a button click filtered to a specific class, click that button, but also click other buttons nearby and confirm they do not trigger the tag. False positives are as problematic as missing events.

Keeping Your GTM Container Maintainable

A GTM container that has been in production for a few years without governance tends to accumulate problems: duplicate tags, triggers that reference deleted variables, and tags with names that made sense to the person who created them but are meaningless to anyone else. This creates maintenance risk and makes debugging harder.

A few practices that keep containers manageable over time: use consistent, descriptive naming for every tag, trigger, and variable. Include the purpose and date in notes fields. Organize tags into folders by function. Archive rather than delete tags that are no longer needed, so there is a record of what was removed and why. Publish only through a change log that documents what changed in each version.

One more thing: every GTM publish should go through a review before it goes live. The person who built the change should not be the only person who reviews it. A second set of eyes catches trigger conditions that are too broad, parameter names that do not match the measurement plan, and tags that are missing consent mode settings.

Custom Events Are Your Competitive Edge

The organizations that get the most value from GA4 are not the ones that installed the tracking pixel and called it done. They are the ones that invested time in designing a measurement architecture specific to their business, building it correctly, and maintaining it over time. Custom events, built on a solid dataLayer foundation and managed in GTM with discipline, are what make the difference between analytics that generates reports and analytics that drives decisions.

This kind of work requires both technical depth and strategic clarity. The technical side covers GTM configuration, dataLayer specification, and GA4 property setup. The strategic side covers deciding what to measure, how to name it, and what questions the data needs to answer. Most teams have one or the other. Combining both is where the value compounds.

At TestedPath, we design and build custom event implementations , from standalone conversion tracking setups to full analytics architecture engagements. We start with your business objectives, work backward to the events and parameters that will help you measure them, and build an implementation that your team can understand and maintain. The result is analytics infrastructure that works the way your business does.

Ready to build analytics that actually answers your questions?

We design custom event tracking from the ground up, based on your business objectives and your actual user journeys. Every engagement starts with a free consultation.

Talk to TestedPath →