DataLayer Naming Conventions
Your dataLayer naming convention is the foundation of your entire analytics implementation. Change a parameter name six months after launch and you’ll spend weeks patching GTM configurations, redefining custom dimensions in GA4, and explaining to your analytics team why historical data no longer matches new data. Define it right from day one and you’ll never have to touch it.
This page documents the complete naming convention for a well-structured implementation. Use it as a reference and copy the structure into your own team’s tracking specification.
Core rule: always use snake_case
Section titled “Core rule: always use snake_case”Every event name and every parameter name uses snake_case — lowercase letters, words separated by underscores, no spaces, no hyphens, no camelCase, no PascalCase.
// ✅ CorrectdataLayer.push({ event: 'add_to_cart', ecommerce: { currency: 'USD', value: 49.99, items: [{ item_id: 'SKU-001', item_name: 'Classic Leather Jacket', item_category: 'Apparel' }] }});
// ❌ Wrong — various incorrect stylesdataLayer.push({ event: 'addToCart', // camelCase ecommerce: { Currency: 'USD', // PascalCase 'item-name': 'Jacket', // hyphens itemCategory: 'Apparel' // camelCase parameter }});The reason to follow snake_case is alignment with GA4. All of GA4’s recommended event names — page_view, purchase, add_to_cart, view_item_list — are snake_case. All of GA4’s auto-collected parameters — page_location, page_title, session_id — are snake_case. When your custom names match the convention of GA4’s built-in names, your implementation looks and behaves consistently.
Reserved prefixes to never use
Section titled “Reserved prefixes to never use”Some prefixes are claimed by Google and will cause silent failures or conflicts.
| Prefix | Owner | What happens if you use it |
|---|---|---|
gtm. | Google Tag Manager | GTM uses this for built-in events (gtm.js, gtm.dom, gtm.load). Your custom event will be ignored or confused with GTM internals. |
ga_ | Google Analytics 4 | Reserved by GA4 for internal parameters. Custom events with this prefix may be dropped. |
google_ | Used by Google products. Avoid entirely. |
// ❌ Never use these prefixesevent: 'gtm.custom_event'event: 'ga_form_submit'event: 'google_conversion'
// ✅ Fineevent: 'form_submit'event: 'custom_conversion'Namespace strategy for custom events
Section titled “Namespace strategy for custom events”When you have events that belong to specific areas of your product, use namespace prefixes to group them. This prevents naming collisions as your event taxonomy grows and makes the dataLayer easier to search and audit.
Recommended namespace prefixes:
| Prefix | Use for |
|---|---|
app_ | Application-specific events that don’t fit GA4 recommended categories |
content_ | Content engagement events (articles, videos, downloads) |
user_ | User-state events beyond GA4’s login/sign_up |
form_ | Form interaction events |
error_ | Error and exception events |
search_ | Search and filter interactions |
// Examples of namespaced eventsdataLayer.push({ event: 'content_article_read' });dataLayer.push({ event: 'content_video_complete' });dataLayer.push({ event: 'form_start' });dataLayer.push({ event: 'form_step_complete' });dataLayer.push({ event: 'error_api_failure' });dataLayer.push({ event: 'user_subscription_upgrade' });GA4 recommended events: use them exactly as specified
Section titled “GA4 recommended events: use them exactly as specified”When GA4 has a recommended event that fits your use case, use the exact GA4 name — no modifications, no additions of your own prefix. GA4 can automatically categorize and pre-configure reports for recommended events. Custom variations lose that benefit.
// ✅ Use GA4 recommended names exactlyevent: 'purchase'event: 'add_to_cart'event: 'view_item'event: 'login'event: 'sign_up'event: 'search'event: 'begin_checkout'
// ❌ Don't rename recommended eventsevent: 'app_purchase' // unnecessary prefixevent: 'ecommerce_purchase' // unnecessary prefixevent: 'buy' // synonym but loses GA4 integrationParameter naming rules
Section titled “Parameter naming rules”Parameters follow the same snake_case rule as events. Additional rules apply:
Use full words, not abbreviations
Section titled “Use full words, not abbreviations”// ✅ Full wordsitem_category: 'Apparel'payment_type: 'credit_card'shipping_tier: 'standard'content_type: 'article'
// ❌ Cryptic abbreviationsitm_cat: 'Apparel'pmt_typ: 'cc'ship_t: 'std'The one exception: widely understood abbreviations like id (not identifier), url (not uniform_resource_locator), and standard measurement units.
Boolean parameters use is_ or has_ prefix
Section titled “Boolean parameters use is_ or has_ prefix”// ✅ Clear boolean namingis_logged_in: trueis_sale_item: falsehas_active_subscription: truehas_cart_items: false
// ❌ Ambiguouslogged_in: true // Is this boolean or a string state?subscription: true // Is this presence or status?Arrays use plural nouns
Section titled “Arrays use plural nouns”// ✅ Plural for arraysitems: [...]categories: [...]tags: [...]filters_applied: [...]
// ❌ Singular for arrays is confusingitem: [...]category: [...]IDs are always strings
Section titled “IDs are always strings”Product IDs, order IDs, user IDs, and any other identifier should always be a string, even if the value looks like a number. IDs are not quantities you perform math on — treat them as labels.
// ✅ IDs as stringsitem_id: 'SKU-12345'transaction_id: 'ORD-2024-98765'user_id: '42813'
// ❌ IDs as numbersitem_id: 12345transaction_id: 98765user_id: 42813If your backend stores IDs as integers, convert them to strings before pushing to the dataLayer. String(product.id) is enough.
Complete naming convention reference table
Section titled “Complete naming convention reference table”| Category | Convention | Example |
|---|---|---|
| Event names | snake_case | view_item, form_submit |
| Parameter names | snake_case | item_name, payment_type |
| Custom event prefix | namespace_description | content_video_play |
| Boolean parameters | is_ or has_ prefix | is_logged_in, has_coupon |
| IDs | snake_case string | item_id, transaction_id |
| Arrays | Plural noun | items, categories |
| Currency codes | ISO 4217, uppercase | USD, EUR, GBP |
| Monetary values | Number, two decimal places | 29.99, 0.00 |
| Dates | ISO 8601 string | 2024-03-15 |
| Reserved prefixes | Never use | gtm., ga_, google_ |
The consistency rule
Section titled “The consistency rule”Once you’ve named something, never rename it without a versioning strategy.
Renaming item_category to product_category mid-implementation means:
- All existing GTM Data Layer Variables reading
item_categoryreturnundefined. - GA4 custom dimensions mapped to
item_categorystop receiving data. - Historical reports show a break in the time series.
- Someone has to find and update every tag, variable, and dimension reference.
The correct approach when you need to rename: version your specification (see Versioning Strategy), run both old and new names in parallel during a transition period, then deprecate the old name with a defined sunset date.
Common mistakes
Section titled “Common mistakes”Using camelCase for event names. The most common error. Developers write addToCart because it feels natural in JavaScript. GA4 won’t match it to add_to_cart — they’re treated as completely different events.
Inventing synonyms for GA4 recommended events. If GA4 has login, don’t create user_login, auth_login, or authentication_success unless they genuinely represent different things. Use the recommended name and add parameters if you need more context.
Inconsistent capitalization in values. Parameter names are case-sensitive in GTM variable paths. item_category and Item_Category are different paths. Enforce lowercase for all keys.
Using spaces or special characters. Spaces, hyphens, slashes, and parentheses in parameter names will cause issues in GTM dot-notation paths and GA4 custom dimension registration. Only letters, numbers, and underscores.