A good GTM naming convention puts the platform first and uses one separator, so every tag reads like 'GA4 - Event - generate_lead (contact form)'. Triggers say how they listen ('CE - form_submit'), variables mirror the data layer ('DLV - form_name'), and event names use GA4's recommended names (generate_lead, not form_submit). The payoff: anyone can open the container and understand what is tracked.
Open someone else’s Google Tag Manager container and you can usually tell in ten seconds whether they had a system. Clean containers read like a table of contents. Messy ones have tags called “Tag,” “Tag copy,” and “GA4 event (new) FINAL,” and nobody, including the person who built it, remembers what fires where.
This is the naming convention we use. It is simple on purpose: put the platform first, use one separator, and let the names describe what fires and where. Learn it once and every container you touch stays readable.
Anyone building or inheriting a GTM container who wants it organized before it grows. It pairs well with the Google Tag Manager beginner’s guide if you are still learning what tags, triggers, and variables are.
The one format to remember
Every tag follows the same shape:
<Platform> - <Type> - <Descriptor> (optional context)
One separator throughout: a space, a hyphen, a space. That is it. Here is the whole system in one screen:
GA4 - Config
GA4 - Event - generate_lead (contact form)
Meta - Base Pixel
Google Ads - Conversion - Lead
Platform first (GA4, Meta, Google Ads) so tags sort by platform automatically. Then the type. Then a plain-English descriptor, with a parenthetical only when the same event fires from more than one place.
Tags
The base tag of any platform is its Config (GA4) or Base Pixel (Meta). It carries no event; it just turns the platform on. Everything else is an Event tag that names the exact event being sent.
| Tag | What it is |
|---|---|
GA4 - Config | The base Google tag. Sets the Measurement ID, fires on all pages. |
GA4 - Event - generate_lead (contact form) | Sends generate_lead when the contact form is submitted. |
Meta - Base Pixel | The Meta pixel’s base code. |
Meta - Event - Lead (contact form) | Meta’s standard Lead event, same trigger. |
Google Ads - Conversion - Lead | Google Ads conversion for a lead. |
cHTML - Cookie Banner | A custom HTML tag (only when no native template exists). |
Prefer the native tag templates from the gallery. Reach for a custom HTML tag only when there is no template, and prefix it cHTML (lowercase c, uppercase HTML) so it is obvious it contains hand-written code.
Triggers
A trigger’s name should say how it listens. The most common one is the Custom Event trigger, which listens for an event in your data layer. Name it with the data layer event verbatim:
CE - form_submit
CE - cta_click
Click - Outbound link
Scroll - 90%
Your site pushes form_submit to the data layer, so your trigger is CE - form_submit. But the GA4 event you send is generate_lead. That is correct: the trigger describes the signal (its raw name), the tag describes the event you send (GA4’s recommended name). Do not rename one to match the other.
Variables
Turn on GTM’s built-in variables before you build anything custom. There is no reason to create a “Page Path” variable when {{Page Path}} already exists. Build a custom variable only for values you push yourself.
| Pattern | Type | Example |
|---|---|---|
DLV - <exact.path> | Data Layer Variable | DLV - form_name, DLV - ecommerce.value |
CJS - <purpose> | Custom JavaScript | CJS - Lowercase Page Path |
Const - <name> | Constant | Const - GA4 Measurement ID |
The key rule: a Data Layer Variable’s name mirrors the real data layer key, dotted path and all. If your site pushes form_location, the variable is DLV - form_location. The name becomes documentation of what is actually in your data layer.
Event names: use what GA4 recommends
This is the rule that keeps your reports clean. GA4 publishes a list of recommended event names, and using them unlocks features and consistent reporting. Send the recommended event when one fits; invent a custom name only when nothing does.
| Action | Send this | Not this |
|---|---|---|
| Lead / contact form submit | generate_lead | form_submit, form_capture |
| Newsletter or account signup | sign_up | subscribe, register |
| Purchase | purchase | order, transaction |
| Add to cart | add_to_cart | cart_add |
| On-site search | search | site_search |
Event names are always lowercase snake_case. When you do need a custom event (say, a generic hero CTA click with no recommended match), keep it clean: cta_click with descriptive parameters. Then register those parameters as custom dimensions in GA4 so they show up in your reports, and mark value events like generate_lead as key events.
GA4’s Enhanced Measurement already collects page views, scrolls, outbound clicks, site search, file downloads, and video plays. Do not recreate these as custom events in GTM; you will only get duplicates. Built-in first, on both sides.
Three finishing touches
- Folders. File every tag, trigger, and variable in a folder, organized by platform (
GA4,Meta,Google Ads) plus a sharedUtilitiesfolder. Nothing loose. The folder list should read like a table of contents. - Consent. Give every tag its consent settings (GA4 tags require
analytics_storage; ad and Meta tags requiread_storage), and turn on the Consent Overview so no tag ships unconfigured. - Publishing. Name every version
YYYY-MM-DD - what changedand write a one-line description of what and why. Your Versions list becomes a changelog you can actually read.
The free template
We are putting together a Google Sheet you can copy: every pattern in this guide as a fill-in-the-blank library for your own tags, triggers, variables, and events, so your whole team names things the same way.
[ Get the template, coming soon ]
Put it to work
Naming is only step one; the point is a container anyone can read. If you are still building yours, these walk through the pieces:
- How to install Google Tag Manager
- How to add GA4 through Google Tag Manager
- How to track button clicks with GTM
Name things this way from the first tag, and the container stays readable no matter how big it gets.