To track a custom event in Google Analytics 4, send an event with your own name and parameters using gtag('event', 'your_event_name', { ... }), a Google Tag Manager GA4 Event tag, or the Create event builder in the GA4 Admin. Then register the parameters as custom dimensions so they appear in reports.
gtag('event', 'newsletter_signup', {method: 'footer_form'}) on the page. Tag Manager: build a trigger, then a Google Analytics: GA4 Event tag with the same name and parameters. No code: go to Admin > Data display > Events > Create event and derive a new event from an existing one. Whichever route you choose, you must then register each parameter under Admin > Data display > Custom definitions, and wait 24 to 48 hours before it reports.This guide assumes you already have a GA4 property with a measurement ID (the G-XXXXXXXXXX string) firing on your site. If you don’t, start with adding Google Analytics to WordPress first. Universal Analytics stopped processing data in 2023 and its interface is gone, so everything below is GA4-only. If you learned analytics on the old category/action/label pattern, the first section is the one that will save you the most time.
How the GA4 event model actually works
Universal Analytics events had a rigid shape: one category, one action, one optional label, one optional numeric value. Four slots, always the same four. GA4 threw that away. An event is now just a name plus up to 25 arbitrary key-value parameters that you define. Nothing is called “category” unless you decide to call it that.
| Old UA event anatomy | GA4 equivalent | What changed in practice |
|---|---|---|
| Event Category (required) | A parameter you invent, or nothing | No longer a reserved slot. Most people fold it into the event name. |
| Event Action (required) | The event name itself | Snake_case verb phrases are the convention: newsletter_signup. |
| Event Label (optional) | Any named parameter | You can now send several labels at once instead of cramming them into one string. |
| Event Value (optional, integer) | value plus currency | Decimals are allowed, and revenue needs a currency code alongside it. |
| Goals, configured in a view | Key events, toggled per event | Views are gone. You flip a switch on the event itself. |
The trade-off: GA4 collects your parameters happily, but it will not show them in a report until you explicitly register them. That single fact accounts for most of the “my event works but I can’t see anything” complaints.
The four types of GA4 event
Knowing which bucket your event falls into tells you how much work you have to do. Google’s own documentation splits them like this.
| Type | Who defines it | Examples | Work required |
|---|---|---|---|
| Automatically collected | first_visit, session_start, user_engagement | None. Fires as soon as the tag loads. | |
| Enhanced measurement | page_view, scroll, click, file_download, form_start, form_submit, video_start | Toggle only, under Admin > Data collection and modification > Data streams. | |
| Recommended | Google names them, you send them | purchase, add_to_cart, sign_up, generate_lead | You implement them, but reports and Google Ads already understand them. |
| Custom | You | pricing_cta_click, demo_requested | Full build, plus custom definitions and explorations to see them. |
generate_lead event slots straight into existing reports and Google Ads conversion imports; a my_lead_thing event does not.Method 1: Send the event with gtag
If the Google tag is on the page directly, one function call is all you need. The pattern is gtag('event', '<name>', {<parameters>}). Here are two real cases.
A newsletter signup
<script>
document.querySelector('#footer-newsletter').addEventListener('submit', function () {
gtag('event', 'newsletter_signup', {
form_location: 'footer',
list_name: 'weekly_digest'
});
});
</script>A pricing-page CTA click with a dollar value
<script>
document.querySelector('#plan-pro-cta').addEventListener('click', function () {
gtag('event', 'pricing_cta_click', {
plan_name: 'pro',
plan_interval: 'monthly',
value: 49.00,
currency: 'USD'
});
});
</script>Two things worth copying from those snippets. First, every parameter name is lowercase snake_case, which keeps your custom definitions tidy later. Second, value is always paired with currency. Send value alone and GA4 will not attribute revenue to it.
Method 2: Send the event with Google Tag Manager
Tag Manager is the better option once you have more than two or three events, because non-developers can add the next one. If GTM isn’t on your site yet, work through installing Google Tag Manager on WordPress before you continue.
To track a video play on a page with an embedded YouTube player:
- In GTM, enable the built-in YouTube Video variables under Variables > Configure (Video Title, Video Percent, Video Status).
- Create a trigger of type YouTube Video. Tick Start, and tick Add JavaScript API support to all YouTube videos.
- Create a tag of type Google Analytics: GA4 Event. Point it at your measurement ID or your existing Google tag.
- Set the Event Name field to
demo_video_play. - Under Event Parameters, add
video_titlemapped to the Video Title variable, andpage_groupmapped to a constant likeproduct. - Attach the trigger, use Preview to confirm it fires once, then publish.
The important detail is that the event name you type in GTM is the exact name GA4 stores. There is no translation layer. Type Demo Video Play with spaces and capitals and that is what you will be filtering on forever.
Method 3: Create the event from an existing one, no code at all
GA4 can mint a new event out of one you already collect. This is perfect for thank-you-page conversions where you don’t want to touch the site.
- Go to Admin > Data display > Events.
- Click Create event, choose your data stream, then Create.
- Name it, for example
quote_request_complete. - Set the matching conditions:
event_nameequalspage_viewANDpage_locationcontains/quote/thank-you. - Leave Copy parameters from the source event ticked so you keep the page data.
page_view, because modifications overwrite the original event rather than adding to it.Register custom dimensions or your parameters stay invisible
This is the step almost everyone skips. GA4 stores your parameter values, but standard reports only expose parameters that have a matching custom definition. Until you create one, the data is in the account and unreachable in the UI.
- Go to Admin > Data display > Custom definitions.
- Click Create custom dimension.
- Give it a readable name (“Plan name”), set Scope to Event, and set Event parameter to the exact parameter string,
plan_name. - Repeat for every parameter you want to slice by. For numeric parameters you want to sum or average, create a custom metric instead.
Mark it as a key event so it counts as a conversion
“Conversions” are now called key events in GA4. From Admin > Data display > Events, find your event in the list and flip the Mark as key event toggle. Allow up to 24 hours for it to appear in standard reports, though Realtime picks it up within minutes. Standard properties can have up to 30 key events; Analytics 360 allows 50.
If you also run Google Ads, linking the accounts lets you import key events as Ads conversions. That’s covered in more depth in our guide to using Google Analytics for marketing.
Verify it with DebugView before you trust it
DebugView lives at Admin > Data display > DebugView and shows the event stream for a single debugging device in near real time. Three ways to get your session into it:
- Install the Google Analytics Debugger Chrome extension and toggle it on.
- Load your page through Google Tag Assistant at tagassistant.google.com, which appends a debug parameter for you.
- Send the
debug_modeparameter yourself.
// Debug every event from this page
gtag('config', 'G-XXXXXXXXXX', { 'debug_mode': true });
// Or debug just one event
gtag('event', 'pricing_cta_click', {
plan_name: 'pro',
debug_mode: true
});One quirk: setting debug_mode to false does not turn debugging off. You have to remove the parameter entirely.
The limits that will bite you
| Limit | Standard property | Why it matters |
|---|---|---|
| Event name length | 40 characters | Long descriptive names get truncated or rejected. |
| Parameters per event | 25 | Automatically added parameters count toward this. |
| Parameter name / value length | 40 / 100 characters | Exceptions: page_title 300, page_referrer 420, page_location 1,000. |
| Event-scoped custom dimensions | 50 | The real ceiling on how many parameters you can report on. |
| User-scoped custom dimensions | 25 | Separate quota from event-scoped. |
| Item-scoped custom dimensions | 10 | Ecommerce only. Up to 27 item-level custom parameters per event. |
| Custom metrics | 50 | For numeric parameters you want to aggregate. |
| Key events | 30 (50 on 360) | Be selective. Not everything is a conversion. |
Upgrading to Analytics 360 raises several volume limits but not the character limits. The full list is in Google’s Analytics data collection limits reference.
Troubleshooting the four failures you’ll actually hit
The event shows in DebugView but never appears in reports
Almost always timing. Standard reports lag behind Realtime, and a brand-new event name can take up to 24 hours to appear in the Events report. If it’s been longer, check that you’re looking in the right place: custom events do not show up in most standard reports, so build a free-form exploration or a custom report instead of hunting through the default set.
A parameter reports as “(not set)”
Three usual causes. You created the custom dimension after the data was collected, and definitions are not retroactive. The parameter name in your custom definition does not exactly match the string in your code, including case. Or the parameter genuinely wasn’t sent on some hits, for example a plan_name that only exists on the pricing page while the event also fires elsewhere.
The event or parameter name is rejected
GA4 refuses parameter names starting with _, firebase_, ga_, google_ or gtag.. A list of event names is reserved too, including session_start, first_visit, user_engagement, app_install and error. Pick a name in your own namespace and the problem disappears.
Every event counts twice
You have the Google tag hardcoded in your theme and deployed through Tag Manager. Remove one. On WordPress this often means an analytics plugin injecting the tag while GTM does the same. The other common version is a click trigger on a link that also navigates, firing once on click and once again on the destination page.
Frequently asked questions
How long does it take for a custom event to show up in GA4?
Realtime and DebugView show it within seconds. Standard reports typically take up to 24 hours for a new event name to appear, and custom dimensions need 24 to 48 hours after creation before they report values. If nothing appears after two days, you have a real implementation problem, not a delay.
Do I need Google Tag Manager to track custom events?
No. A single gtag('event', ...) call works fine, and the Create event builder in Admin needs no code at all. GTM earns its place once you have many events, several people touching tracking, or third-party pixels to manage alongside GA4.
What is the difference between an event and a key event?
Every measured interaction is an event. A key event is an event you have flagged as commercially important, which makes it eligible for conversion reporting and for import into Google Ads. Key events replaced the term “conversions” inside GA4 reports. Standard properties allow up to 30.
Why can’t I see my event parameters in reports?
Because parameters are only queryable after you register them under Admin > Data display > Custom definitions. GA4 collects them regardless, but the reporting layer will not expose an unregistered parameter, and registration is not retroactive.
Can I track a custom event without editing my site’s code?
Yes, if the behavior you want is already visible in data GA4 collects. Enhanced measurement covers scrolls, outbound clicks, file downloads and form submissions with a toggle, and the Create event builder can turn a page_view on a specific URL into a named conversion event. Anything genuinely new needs code or a tag.
Wrapping up
The mechanics of sending a custom event are the easy part. What separates a useful GA4 setup from a noisy one is naming discipline and registering your parameters: pick snake_case names, reuse Google’s recommended event names wherever they fit, register every parameter you plan to segment by, and mark only genuine business outcomes as key events.
Start with two or three events that map to decisions you actually make, verify them in DebugView, and expand from there. If you’re also running paid social alongside search, the same discipline applies on the ad platforms, and our walkthrough of setting up the TikTok Pixel uses the same event-plus-parameters thinking. Google’s Set up events developer guide is the reference to keep open while you build.

