Initial commit
This commit is contained in:
268
skills/ga4-custom-dimensions/SKILL.md
Normal file
268
skills/ga4-custom-dimensions/SKILL.md
Normal file
@@ -0,0 +1,268 @@
|
||||
---
|
||||
name: ga4-custom-dimensions
|
||||
description: Expert guidance for creating and managing Google Analytics 4 custom dimensions and metrics including event-scoped, user-scoped, and item-scoped dimensions with proper registration and scoping. Use when registering custom parameters as custom dimensions, understanding scope differences (event vs user vs item), creating custom dimensions in GA4 Admin, troubleshooting why custom dimensions aren't appearing in reports, working with custom metrics, implementing calculated metrics, or managing dimension limits (25 user-scoped, 50 event-scoped in standard GA4).
|
||||
---
|
||||
|
||||
# GA4 Custom Dimensions
|
||||
|
||||
## Overview
|
||||
|
||||
Custom dimensions and metrics enable transformation of event parameters into reportable fields in GA4. This skill covers the complete workflow: sending parameters in events, registering them as dimensions, selecting correct scopes, and troubleshooting missing data.
|
||||
|
||||
All custom parameters remain invisible in GA4 reports until registered as custom dimensions. Registration requires understanding three scope types (event, user, item), following naming conventions, and accounting for the 24-48 hour processing delay.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Invoke this skill when:
|
||||
- Registering custom event parameters as event-scoped dimensions
|
||||
- Setting up user properties as user-scoped custom dimensions
|
||||
- Creating item-scoped dimensions for ecommerce tracking
|
||||
- Implementing custom metrics for numerical tracking
|
||||
- Building calculated metrics from existing metrics
|
||||
- Troubleshooting why custom parameters don't appear in reports
|
||||
- Planning dimension strategy within account limits (50 event/25 user/10 item)
|
||||
- Understanding scope differences for specific business needs
|
||||
- Dealing with the 24-48 hour data population delay
|
||||
|
||||
## Core Concepts: Understanding Scopes
|
||||
|
||||
GA4 uses three **scopes** that determine what data the parameter applies to:
|
||||
|
||||
### Event Scope (Single Event Only)
|
||||
|
||||
**Applies To:** Individual event occurrence
|
||||
**Lifespan:** That specific event only
|
||||
**Use:** Event-specific information
|
||||
|
||||
Event-scoped dimensions track data unique to each event. Once registered, they appear only for that event type in reports.
|
||||
|
||||
```javascript
|
||||
gtag('event', 'button_click', {
|
||||
'button_name': 'Subscribe', // Event-scoped
|
||||
'button_location': 'header', // Event-scoped
|
||||
'button_id': 'btn_subscribe_01' // Event-scoped
|
||||
});
|
||||
```
|
||||
|
||||
**Examples:** Which form was submitted? What video was watched? Which page in sequence? Which button was clicked?
|
||||
|
||||
### User Scope (All User Events)
|
||||
|
||||
**Applies To:** All events from that user
|
||||
**Lifespan:** Session persistence (until cleared)
|
||||
**Use:** User attributes that persist
|
||||
|
||||
User-scoped dimensions (user properties) apply to every event from that user during the session. Set once, they persist across multiple events.
|
||||
|
||||
```javascript
|
||||
gtag('set', {
|
||||
'subscription_tier': 'premium', // User-scoped
|
||||
'customer_lifetime_value': 5000, // User-scoped
|
||||
'preferred_language': 'en' // User-scoped
|
||||
});
|
||||
```
|
||||
|
||||
**Examples:** What subscription level? What's customer lifetime value? What language preference? What company size?
|
||||
|
||||
### Item Scope (Product-Level Data)
|
||||
|
||||
**Applies To:** Individual items in ecommerce events
|
||||
**Lifespan:** That transaction only
|
||||
**Use:** Product-specific information
|
||||
|
||||
Item-scoped dimensions apply only to products in purchase, add_to_cart, and related ecommerce events.
|
||||
|
||||
```javascript
|
||||
gtag('event', 'purchase', {
|
||||
'items': [
|
||||
{
|
||||
'item_id': 'SKU_123',
|
||||
'item_name': 'Blue T-Shirt',
|
||||
'item_color': 'blue', // Item-scoped
|
||||
'item_size': 'large', // Item-scoped
|
||||
'supplier': 'Vendor A' // Item-scoped
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
**Examples:** Which color was purchased? What size items sell best? Which supplier's products? Product quality rating?
|
||||
|
||||
## Registration Workflow
|
||||
|
||||
### Step 1: Send Parameter in Event Code
|
||||
|
||||
Send the parameter in either gtag.js event call, gtag('set') for user properties, or in items array:
|
||||
|
||||
```javascript
|
||||
// Event parameter
|
||||
gtag('event', 'watch_video', {
|
||||
'video_duration': 1200,
|
||||
'video_quality': 'hd'
|
||||
});
|
||||
|
||||
// User parameter
|
||||
gtag('set', {
|
||||
'customer_segment': 'enterprise'
|
||||
});
|
||||
|
||||
// Item parameter
|
||||
gtag('event', 'purchase', {
|
||||
'items': [{
|
||||
'item_id': 'SKU_123',
|
||||
'supplier': 'Vendor A' // NEW parameter
|
||||
}]
|
||||
});
|
||||
```
|
||||
|
||||
### Step 2: Verify in DebugView
|
||||
|
||||
Before registration, confirm the parameter appears in DebugView:
|
||||
|
||||
1. Go to Admin → DebugView
|
||||
2. Enable Google Analytics Debugger Chrome extension
|
||||
3. Trigger the event that sends parameter
|
||||
4. See parameter in DebugView event details
|
||||
5. Note exact parameter name (case-sensitive)
|
||||
|
||||
### Step 3: Register as Custom Dimension
|
||||
|
||||
Navigate to Admin → Data Display → Custom Definitions:
|
||||
|
||||
1. Click "Create Custom Dimension"
|
||||
2. Fill form:
|
||||
- **Dimension Name:** Human-friendly name (appears in reports, e.g., "Video Quality")
|
||||
- **Scope:** Select Event, User, or Item
|
||||
- **Event Parameter:** Exact parameter name from code (case-sensitive, e.g., "video_quality")
|
||||
- **Description:** Optional notes
|
||||
3. Click Save
|
||||
|
||||
### Step 4: Wait for Data Population
|
||||
|
||||
**Critical:** Custom dimensions don't appear in reports immediately. Wait 24-48 hours for:
|
||||
- Historical data retroactively processed
|
||||
- New incoming data to populate
|
||||
- Dimension to appear in dimension selectors
|
||||
|
||||
Do not create duplicate dimensions while waiting.
|
||||
|
||||
### Step 5: Use in Reports
|
||||
|
||||
After 24-48 hours, access custom dimensions:
|
||||
- Standard Reports: Add custom dimension as column
|
||||
- Explorations: Select from Dimension picker
|
||||
- Filters/Segments: Filter by custom dimension values
|
||||
- Google Ads: Export for audience building (if linked)
|
||||
|
||||
## Dimension Limits & Quotas
|
||||
|
||||
Standard GA4 Property limits:
|
||||
- **User-scoped:** 25 custom dimensions
|
||||
- **Event-scoped:** 50 custom dimensions
|
||||
- **Item-scoped:** 10 custom dimensions
|
||||
- **Custom metrics:** 50
|
||||
- **Calculated metrics:** 5
|
||||
|
||||
GA4 360 properties have higher limits (100 user, 125 event, 25 item). Plan dimensions strategically.
|
||||
|
||||
## Custom Metrics Implementation
|
||||
|
||||
### Standard Custom Metrics
|
||||
|
||||
Create metrics for numerical tracking:
|
||||
|
||||
```javascript
|
||||
gtag('event', 'video_watched', {
|
||||
'video_title': 'GA4 Tutorial',
|
||||
'minutes_watched': 45, // METRIC
|
||||
'completion_rate': 85 // METRIC
|
||||
});
|
||||
```
|
||||
|
||||
Register in Custom Definitions:
|
||||
1. Click "Create Custom Metric"
|
||||
2. Metric Name: "Minutes Watched"
|
||||
3. Type: Standard
|
||||
4. Measurement Unit: Minutes (optional)
|
||||
5. Event Parameter: "minutes_watched"
|
||||
6. Save and wait 24-48 hours
|
||||
|
||||
### Calculated Metrics
|
||||
|
||||
Create metrics derived from mathematical operations on existing metrics:
|
||||
|
||||
```
|
||||
Calculated Metric: "Revenue per User"
|
||||
= revenue / users
|
||||
|
||||
Calculated Metric: "Conversion Rate"
|
||||
= conversions / sessions * 100
|
||||
```
|
||||
|
||||
Create in Custom Definitions:
|
||||
1. Click "Create Custom Metric"
|
||||
2. Metric Name: "Revenue per User"
|
||||
3. Type: Calculated
|
||||
4. Formula: `revenue / users`
|
||||
5. Save (no processing delay)
|
||||
|
||||
## Common Troubleshooting
|
||||
|
||||
**Custom dimension doesn't appear after 48 hours:**
|
||||
- Verify parameter name matches exactly (case-sensitive)
|
||||
- Confirm new events are actually sending parameter
|
||||
- Check DebugView to see current events with parameter
|
||||
- Ensure scope selection was correct
|
||||
- Not all parameter values may appear if threshold not met
|
||||
|
||||
**Parameter appears in DebugView but not in reports:**
|
||||
- Normal during first 24-48 hours
|
||||
- Check Realtime reports first (available sooner)
|
||||
- Verify at least 1000 events with that parameter for visibility
|
||||
- Low-traffic parameters may not appear
|
||||
|
||||
**Dimension quota exceeded:**
|
||||
- Standard GA4: Maximum 50 event-scoped dimensions
|
||||
- Plan which dimensions are essential
|
||||
- Delete unused dimensions if needed
|
||||
- Consider GA4 360 for higher limits
|
||||
|
||||
**Multiple users show same custom dimension value:**
|
||||
- For user-scoped: Expected (applies to all user events)
|
||||
- For event-scoped: Normal if multiple events send same value
|
||||
- For item-scoped: Normal across products
|
||||
|
||||
## Integration with Other Skills
|
||||
|
||||
- **ga4-events-fundamentals** - Understand event structure and parameter basics
|
||||
- **ga4-custom-events** - Create parameters to register as dimensions
|
||||
- **ga4-user-tracking** - User properties (user-scoped dimensions)
|
||||
- **ga4-reporting** - Use custom dimensions in standard reports and explorations
|
||||
|
||||
## References
|
||||
|
||||
- **references/scopes-complete-guide.md** - Detailed scope examples and decision framework
|
||||
- **references/dimension-registration-steps.md** - Step-by-step Admin UI walkthrough
|
||||
- **references/custom-metrics-guide.md** - Standard and calculated metrics
|
||||
- **references/dimension-limits-quotas.md** - Account limits and best practices
|
||||
- **references/dimension-troubleshooting.md** - Solutions for common issues
|
||||
|
||||
## Quick Reference
|
||||
|
||||
**Scope Selection Matrix:**
|
||||
- Event-specific data → Event scope
|
||||
- User attributes → User scope
|
||||
- Product data in ecommerce → Item scope
|
||||
|
||||
**Registration Process:**
|
||||
1. Send parameter in event code
|
||||
2. Verify in DebugView
|
||||
3. Admin → Custom Definitions → Create
|
||||
4. Wait 24-48 hours
|
||||
5. Use in reports
|
||||
|
||||
**Parameter Limits:**
|
||||
- Parameter name: 40 characters max
|
||||
- Parameter value: 100 characters max (exceptions: page_location 1000, page_title 300)
|
||||
- Parameters per event: 25 max
|
||||
- Items array max: 27 items
|
||||
@@ -0,0 +1,542 @@
|
||||
# Custom Dimension Registration Templates
|
||||
|
||||
Copy and customize these templates for your custom dimensions registration.
|
||||
|
||||
---
|
||||
|
||||
## Template 1: Event-Scoped Dimension - Form Tracking
|
||||
|
||||
### Code Implementation
|
||||
|
||||
```javascript
|
||||
// On form submit event
|
||||
document.querySelectorAll('form').forEach(form => {
|
||||
form.addEventListener('submit', function(e) {
|
||||
// Get form details
|
||||
const formName = this.getAttribute('name') || this.getAttribute('id');
|
||||
const formId = this.getAttribute('id');
|
||||
|
||||
// Send to GA4
|
||||
gtag('event', 'form_submit', {
|
||||
'form_name': formName,
|
||||
'form_id': formId,
|
||||
'form_destination': this.getAttribute('action')
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Admin Registration Details
|
||||
|
||||
**Dimension 1:**
|
||||
- **Dimension Name:** Form Name
|
||||
- **Scope:** Event
|
||||
- **Event Parameter:** form_name
|
||||
- **Description:** Name of form submitted (contact, newsletter, demo request, etc)
|
||||
|
||||
**Dimension 2:**
|
||||
- **Dimension Name:** Form ID
|
||||
- **Scope:** Event
|
||||
- **Event Parameter:** form_id
|
||||
- **Description:** HTML ID attribute of submitted form
|
||||
|
||||
**Dimension 3:**
|
||||
- **Dimension Name:** Form Destination
|
||||
- **Scope:** Event
|
||||
- **Event Parameter:** form_destination
|
||||
- **Description:** Form submission destination URL or page
|
||||
|
||||
### Expected Report Output
|
||||
|
||||
```
|
||||
Form Name Form Submissions Avg. Engagement Time
|
||||
================================================================
|
||||
Contact Form 245 42 seconds
|
||||
Newsletter Signup 189 15 seconds
|
||||
Demo Request 78 85 seconds
|
||||
Product Inquiry 156 38 seconds
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Template 2: User-Scoped Dimension - Customer Tier
|
||||
|
||||
### Code Implementation
|
||||
|
||||
```javascript
|
||||
// After user login/authentication
|
||||
function setUserProperties(user) {
|
||||
// Determine subscription tier
|
||||
let tier = 'free';
|
||||
if (user.isPaidSubscriber) {
|
||||
tier = user.premiumTier || 'pro';
|
||||
}
|
||||
|
||||
gtag('set', {
|
||||
'subscription_tier': tier,
|
||||
'customer_id': user.id || 'guest',
|
||||
'account_age_days': Math.floor(
|
||||
(new Date() - new Date(user.createdDate)) / (1000 * 60 * 60 * 24)
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
// Call on page load if logged in
|
||||
if (window.currentUser) {
|
||||
setUserProperties(window.currentUser);
|
||||
}
|
||||
```
|
||||
|
||||
### Admin Registration Details
|
||||
|
||||
**Dimension 1:**
|
||||
- **Dimension Name:** Subscription Tier
|
||||
- **Scope:** User
|
||||
- **User Property:** subscription_tier
|
||||
- **Description:** User's plan type: free, pro, enterprise, trial
|
||||
|
||||
**Dimension 2:**
|
||||
- **Dimension Name:** Customer ID
|
||||
- **Scope:** User
|
||||
- **User Property:** customer_id
|
||||
- **Description:** Internal customer identifier (hashed)
|
||||
|
||||
**Dimension 3:**
|
||||
- **Dimension Name:** Account Age (Days)
|
||||
- **Scope:** User
|
||||
- **User Property:** account_age_days
|
||||
- **Description:** Days since account creation
|
||||
|
||||
### Expected Report Output
|
||||
|
||||
```
|
||||
Subscription Tier Users Avg. Sessions Revenue
|
||||
======================================================
|
||||
Free 2,450 1.8 $0
|
||||
Pro 890 5.2 $8,900
|
||||
Enterprise 34 12.1 $45,000
|
||||
Trial 156 3.2 $0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Template 3: Item-Scoped Dimension - Product Color
|
||||
|
||||
### Code Implementation
|
||||
|
||||
```javascript
|
||||
// On purchase event
|
||||
function trackPurchase(order) {
|
||||
const items = order.products.map(product => ({
|
||||
'item_id': product.sku,
|
||||
'item_name': product.name,
|
||||
'price': product.price,
|
||||
'quantity': product.quantity,
|
||||
'item_category': product.category,
|
||||
// CUSTOM ITEM-SCOPED DIMENSION
|
||||
'item_color': product.color || 'not_specified'
|
||||
}));
|
||||
|
||||
gtag('event', 'purchase', {
|
||||
'transaction_id': order.id,
|
||||
'value': order.total,
|
||||
'currency': 'USD',
|
||||
'items': items
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Admin Registration Details
|
||||
|
||||
**Dimension 1:**
|
||||
- **Dimension Name:** Item Color
|
||||
- **Scope:** Item
|
||||
- **Event Parameter:** item_color
|
||||
- **Description:** Color variant of product (red, blue, green, black, etc)
|
||||
|
||||
### Expected Report Output
|
||||
|
||||
```
|
||||
Item Color Items Purchased Revenue Avg. Price
|
||||
=========================================================
|
||||
Blue 1,234 $45,987 $37.28
|
||||
Black 987 $38,976 $39.45
|
||||
Red 654 $23,456 $35.88
|
||||
Green 432 $16,789 $38.86
|
||||
Not Specified 123 $4,567 $37.14
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Template 4: Event-Scoped Dimension - Video Quality
|
||||
|
||||
### Code Implementation
|
||||
|
||||
```javascript
|
||||
// For video player that tracks quality changes
|
||||
class VideoPlayer {
|
||||
constructor(containerId) {
|
||||
this.container = document.getElementById(containerId);
|
||||
this.videoTitle = this.container.getAttribute('data-video-title');
|
||||
this.currentQuality = 'auto';
|
||||
|
||||
// Track when quality changes
|
||||
this.setupQualityTracking();
|
||||
}
|
||||
|
||||
setupQualityTracking() {
|
||||
this.container.addEventListener('qualitychange', (e) => {
|
||||
this.currentQuality = e.detail.quality;
|
||||
|
||||
gtag('event', 'video_quality_change', {
|
||||
'video_title': this.videoTitle,
|
||||
'new_quality': this.currentQuality
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onVideoComplete() {
|
||||
gtag('event', 'video_complete', {
|
||||
'video_title': this.videoTitle,
|
||||
'video_quality': this.currentQuality,
|
||||
'watch_time_minutes': Math.floor(this.duration / 60),
|
||||
'completion_percentage': 100
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize
|
||||
const player = new VideoPlayer('video-player');
|
||||
```
|
||||
|
||||
### Admin Registration Details
|
||||
|
||||
**Dimension 1:**
|
||||
- **Dimension Name:** Video Quality
|
||||
- **Scope:** Event
|
||||
- **Event Parameter:** video_quality
|
||||
- **Description:** Video quality setting (auto, 360p, 480p, 720p, 1080p)
|
||||
|
||||
**Dimension 2:**
|
||||
- **Dimension Name:** New Quality
|
||||
- **Scope:** Event
|
||||
- **Event Parameter:** new_quality
|
||||
- **Description:** Quality selected after quality change event
|
||||
|
||||
### Expected Report Output
|
||||
|
||||
```
|
||||
Video Quality Video Completes Avg. Watch Time Completion %
|
||||
==================================================================
|
||||
1080p 345 18 minutes 92%
|
||||
720p 289 16 minutes 88%
|
||||
480p 156 14 minutes 76%
|
||||
360p 89 10 minutes 62%
|
||||
Auto 421 17 minutes 85%
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Template 5: User-Scoped Dimension - Company Type
|
||||
|
||||
### Code Implementation
|
||||
|
||||
```javascript
|
||||
// After user signup/login with company info
|
||||
function setCompanyProperties(company) {
|
||||
let companyType = 'unknown';
|
||||
|
||||
if (company.employees < 10) {
|
||||
companyType = 'micro';
|
||||
} else if (company.employees < 50) {
|
||||
companyType = 'small';
|
||||
} else if (company.employees < 500) {
|
||||
companyType = 'medium';
|
||||
} else {
|
||||
companyType = 'enterprise';
|
||||
}
|
||||
|
||||
gtag('set', {
|
||||
'company_type': companyType,
|
||||
'company_size': company.employees,
|
||||
'industry': company.industry || 'other'
|
||||
});
|
||||
}
|
||||
|
||||
// Usage
|
||||
if (window.userData && window.userData.company) {
|
||||
setCompanyProperties(window.userData.company);
|
||||
}
|
||||
```
|
||||
|
||||
### Admin Registration Details
|
||||
|
||||
**Dimension 1:**
|
||||
- **Dimension Name:** Company Type
|
||||
- **Scope:** User
|
||||
- **User Property:** company_type
|
||||
- **Description:** Company size category (micro, small, medium, enterprise)
|
||||
|
||||
**Dimension 2:**
|
||||
- **Dimension Name:** Company Size (Employees)
|
||||
- **Scope:** User
|
||||
- **User Property:** company_size
|
||||
- **Description:** Number of employees
|
||||
|
||||
**Dimension 3:**
|
||||
- **Dimension Name:** Industry
|
||||
- **Scope:** User
|
||||
- **User Property:** industry
|
||||
- **Description:** Company industry classification
|
||||
|
||||
### Expected Report Output
|
||||
|
||||
```
|
||||
Company Type Users Conversions Avg. Deal Size
|
||||
====================================================
|
||||
Enterprise 45 34 $45,000
|
||||
Medium 156 89 $12,500
|
||||
Small 234 156 $4,200
|
||||
Micro 567 123 $1,500
|
||||
Unknown 198 45 $2,800
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Template 6: Item-Scoped Dimension - Product Supplier
|
||||
|
||||
### Code Implementation
|
||||
|
||||
```javascript
|
||||
// Ecommerce inventory tracking with supplier info
|
||||
function trackAddToCart(product) {
|
||||
gtag('event', 'add_to_cart', {
|
||||
'items': [{
|
||||
'item_id': product.sku,
|
||||
'item_name': product.name,
|
||||
'price': product.price,
|
||||
'quantity': product.quantity,
|
||||
'item_category': product.category,
|
||||
// CUSTOM ITEM-SCOPED DIMENSION
|
||||
'supplier': product.supplier || 'internal',
|
||||
'warehouse': product.warehouseLocation || 'us_east'
|
||||
}],
|
||||
'value': product.price * product.quantity,
|
||||
'currency': 'USD'
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Admin Registration Details
|
||||
|
||||
**Dimension 1:**
|
||||
- **Dimension Name:** Item Supplier
|
||||
- **Scope:** Item
|
||||
- **Event Parameter:** supplier
|
||||
- **Description:** Supplier/vendor of product (Vendor A, Vendor B, Internal, Dropship)
|
||||
|
||||
**Dimension 2:**
|
||||
- **Dimension Name:** Warehouse Location
|
||||
- **Scope:** Item
|
||||
- **Event Parameter:** warehouse
|
||||
- **Description:** Warehouse location for item (us_east, us_west, eu, asia)
|
||||
|
||||
### Expected Report Output
|
||||
|
||||
```
|
||||
Supplier Items in Cart Carts Conversion Rate
|
||||
========================================================
|
||||
Vendor A 2,345 567 45%
|
||||
Vendor B 1,876 412 38%
|
||||
Internal 987 298 52%
|
||||
Dropship 654 156 27%
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Template 7: Event-Scoped Dimension - Button Click
|
||||
|
||||
### Code Implementation
|
||||
|
||||
```javascript
|
||||
// CTA button tracking across page
|
||||
function trackButtonClicks() {
|
||||
document.querySelectorAll('[data-track-button]').forEach(button => {
|
||||
button.addEventListener('click', function(e) {
|
||||
// Extract button information
|
||||
const buttonName = this.getAttribute('data-button-name') ||
|
||||
this.innerText.trim() ||
|
||||
'unknown_button';
|
||||
const buttonLocation = this.getAttribute('data-location') ||
|
||||
'unknown_location';
|
||||
const destination = this.getAttribute('href') ||
|
||||
this.getAttribute('data-destination') ||
|
||||
'(none)';
|
||||
|
||||
gtag('event', 'button_click', {
|
||||
'button_name': buttonName,
|
||||
'button_location': buttonLocation,
|
||||
'destination': destination
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize on page load
|
||||
document.addEventListener('DOMContentLoaded', trackButtonClicks);
|
||||
```
|
||||
|
||||
### Admin Registration Details
|
||||
|
||||
**Dimension 1:**
|
||||
- **Dimension Name:** Button Name
|
||||
- **Scope:** Event
|
||||
- **Event Parameter:** button_name
|
||||
- **Description:** Text/label of clicked button
|
||||
|
||||
**Dimension 2:**
|
||||
- **Dimension Name:** Button Location
|
||||
- **Scope:** Event
|
||||
- **Event Parameter:** button_location
|
||||
- **Description:** Position on page (hero, sidebar, footer, etc)
|
||||
|
||||
**Dimension 3:**
|
||||
- **Dimension Name:** Destination
|
||||
- **Scope:** Event
|
||||
- **Event Parameter:** destination
|
||||
- **Description:** Where button leads (URL or action)
|
||||
|
||||
### Expected Report Output
|
||||
|
||||
```
|
||||
Button Name Button Location Clicks Conversion %
|
||||
===========================================================
|
||||
Sign Up Now Hero Section 1,234 8.5%
|
||||
Learn More Middle Section 789 5.2%
|
||||
Get Started Footer 456 12.1%
|
||||
Free Trial Sidebar 678 9.8%
|
||||
Contact Us Header 345 15.3%
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Template 8: Documentation Template for Each Dimension
|
||||
|
||||
**Print this for every custom dimension and keep in shared documentation:**
|
||||
|
||||
```
|
||||
═══════════════════════════════════════════════════════════
|
||||
CUSTOM DIMENSION DOCUMENTATION
|
||||
|
||||
Dimension Name: [NAME]
|
||||
Registered: [DATE]
|
||||
Status: [ACTIVE/DEPRECATED]
|
||||
|
||||
BASIC INFORMATION
|
||||
─────────────────
|
||||
GA4 Dimension Name: [Display name in reports]
|
||||
Parameter Name: [Name in code]
|
||||
Scope: [Event / User / Item]
|
||||
Description: [What it tracks]
|
||||
|
||||
IMPLEMENTATION
|
||||
──────────────
|
||||
Owner/Creator: [Person name]
|
||||
Code Location: [File path]
|
||||
Event Name(s): [Which events send this parameter]
|
||||
Approximate Events/Month: [Volume estimate]
|
||||
|
||||
BUSINESS CONTEXT
|
||||
────────────────
|
||||
Purpose: [Why we track this]
|
||||
Business Impact: [How it's used]
|
||||
Teams Using: [Marketing, Product, Analytics, etc.]
|
||||
Report Location: [Which reports show this]
|
||||
|
||||
DATA QUALITY
|
||||
────────────
|
||||
Data Starts: [Date dimension was activated]
|
||||
Current Status: [Actively used / Occasionally used / Dormant]
|
||||
Data Quality Issues: [Any known issues]
|
||||
|
||||
DEPENDENCIES
|
||||
─────────────
|
||||
Related Dimensions: [Other dimensions it works with]
|
||||
Related Events: [Which events send this]
|
||||
Related Metrics: [Any related metrics]
|
||||
|
||||
NOTES
|
||||
─────
|
||||
[Any additional context]
|
||||
|
||||
═══════════════════════════════════════════════════════════
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Copy-Paste: Implementation Checklist
|
||||
|
||||
```markdown
|
||||
## Custom Dimension Implementation Checklist
|
||||
|
||||
### Pre-Implementation
|
||||
- [ ] Dimension name approved by team
|
||||
- [ ] Parameter name finalized
|
||||
- [ ] Scope decided (Event/User/Item)
|
||||
- [ ] Code location identified
|
||||
- [ ] Documentation drafted
|
||||
|
||||
### Implementation
|
||||
- [ ] Parameter added to event code
|
||||
- [ ] Code deployed to development
|
||||
- [ ] Code tested in development
|
||||
- [ ] Code deployed to production
|
||||
- [ ] Code monitoring in place
|
||||
|
||||
### Verification
|
||||
- [ ] Parameter appears in DebugView
|
||||
- [ ] Parameter name matches registration (case-sensitive)
|
||||
- [ ] Parameter values are accurate
|
||||
- [ ] Dimension created in Admin
|
||||
- [ ] Wait 24-48 hours for data population
|
||||
|
||||
### Post-Implementation
|
||||
- [ ] Dimension appears in reports
|
||||
- [ ] Data accuracy verified
|
||||
- [ ] Team documentation updated
|
||||
- [ ] Dashboards created (if applicable)
|
||||
- [ ] Team training completed
|
||||
- [ ] Added to dimension inventory
|
||||
- [ ] Quarterly review scheduled
|
||||
|
||||
### Notes
|
||||
[Any issues or observations]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Template: GA4 Dimension Inventory Spreadsheet
|
||||
|
||||
**Use this to track all dimensions:**
|
||||
|
||||
| Dimension Name | Parameter Name | Scope | Event | Owner | Status | Created | Notes |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| Form Name | form_name | Event | form_submit | John | Active | 2024-09 | Core tracking |
|
||||
| Button Name | button_name | Event | button_click | Sarah | Active | 2024-09 | Updated Sept |
|
||||
| Subscription Tier | subscription_tier | User | all | Mike | Active | 2024-08 | Critical |
|
||||
| Video Quality | video_quality | Event | video_watch | Jane | Active | 2024-10 | New tracking |
|
||||
| Item Color | item_color | Item | purchase | Alex | Active | 2024-09 | Ecommerce |
|
||||
| Test Param | test_parameter | Event | test_event | Dev | Deprecated | 2024-11 | Delete after 11/20 |
|
||||
|
||||
**Columns to include:**
|
||||
- Dimension Name (display name)
|
||||
- Parameter Name (code name)
|
||||
- Scope (Event/User/Item)
|
||||
- Event (which event sends it)
|
||||
- Owner (who created)
|
||||
- Status (Active/Deprecated/Test)
|
||||
- Created (date)
|
||||
- Last Modified (date)
|
||||
- Notes (any details)
|
||||
- Quota Usage (which quota it counts toward)
|
||||
|
||||
621
skills/ga4-custom-dimensions/references/custom-metrics-guide.md
Normal file
621
skills/ga4-custom-dimensions/references/custom-metrics-guide.md
Normal file
@@ -0,0 +1,621 @@
|
||||
# Custom Metrics & Calculated Metrics Complete Guide
|
||||
|
||||
## Understanding GA4 Metrics
|
||||
|
||||
**Metrics** in GA4 are measurements or counts of user activity. They answer "How much?" or "How many?" questions.
|
||||
|
||||
**Built-in GA4 Metrics (Examples):**
|
||||
- users
|
||||
- sessions
|
||||
- events
|
||||
- pageViews
|
||||
- revenue
|
||||
- conversions
|
||||
|
||||
**Custom Metrics** extend GA4 with business-specific numerical tracking.
|
||||
|
||||
---
|
||||
|
||||
## Standard Custom Metrics
|
||||
|
||||
### What Are Custom Metrics?
|
||||
|
||||
Custom metrics track numerical values associated with events. Unlike custom dimensions (which are categorical), metrics are numbers that aggregate and calculate.
|
||||
|
||||
**Use custom metrics for:**
|
||||
- Quantities (items purchased, users in queue)
|
||||
- Durations (video watch time, form fill time)
|
||||
- Ratings (user satisfaction score, product rating)
|
||||
- Percentages (completion rate, engagement rate)
|
||||
- Monetary values (order value, customer lifetime value)
|
||||
- Any numerical KPI
|
||||
|
||||
### Custom Metric Implementation
|
||||
|
||||
**Step 1: Send Numerical Parameter in Event**
|
||||
|
||||
```javascript
|
||||
// Video completion tracking
|
||||
gtag('event', 'video_watched', {
|
||||
'video_title': 'GA4 Basics',
|
||||
'video_duration': 1200, // seconds - METRIC
|
||||
'minutes_watched': 18, // METRIC
|
||||
'completion_percentage': 85 // METRIC
|
||||
});
|
||||
|
||||
// E-commerce order tracking
|
||||
gtag('event', 'purchase', {
|
||||
'transaction_id': 'TXN_123',
|
||||
'items': [...]
|
||||
// Note: 'value' parameter in purchase is auto-metric
|
||||
'avg_item_price': 45.50, // METRIC
|
||||
'discount_amount': 15.00 // METRIC
|
||||
});
|
||||
|
||||
// Form completion tracking
|
||||
gtag('event', 'form_submit', {
|
||||
'form_name': 'contact',
|
||||
'form_fields_filled': 8, // METRIC
|
||||
'time_to_submit': 120, // seconds - METRIC
|
||||
'form_abandonment_rate': 0 // METRIC
|
||||
});
|
||||
```
|
||||
|
||||
**Important:** Send as numerical values, not strings.
|
||||
|
||||
```javascript
|
||||
// CORRECT
|
||||
'duration': 120 // Number
|
||||
|
||||
// WRONG
|
||||
'duration': '120' // String - will be treated as dimension
|
||||
'duration': '120s' // String - invalid
|
||||
```
|
||||
|
||||
### Step 2: Verify in DebugView
|
||||
|
||||
1. GA4 Admin → DebugView
|
||||
2. Trigger event with metric parameter
|
||||
3. Click event in left panel
|
||||
4. See parameter in event details
|
||||
5. Confirm value is numerical
|
||||
|
||||
**DebugView Example:**
|
||||
|
||||
```
|
||||
Event: video_watched
|
||||
|
||||
Parameters:
|
||||
- video_title: "GA4 Basics"
|
||||
- video_duration: 1200
|
||||
- minutes_watched: 18
|
||||
- completion_percentage: 85
|
||||
```
|
||||
|
||||
### Step 3: Register Custom Metric
|
||||
|
||||
1. Admin → Data Display → Custom Definitions
|
||||
2. Click **"Create Custom Metric"** button
|
||||
3. Fill the form:
|
||||
|
||||
| Field | Entry | Example |
|
||||
|-------|-------|---------|
|
||||
| Metric Name | Display name | "Video Duration (seconds)" |
|
||||
| Type | Select "Standard" | Standard |
|
||||
| Measurement Unit | (Optional) unit for reporting | "seconds" |
|
||||
| Event Parameter | Parameter name | "video_duration" |
|
||||
| Description | What it tracks | "Length of video watched in seconds" |
|
||||
|
||||
4. Click **Save**
|
||||
5. Wait 24-48 hours for data population
|
||||
|
||||
### Step 4: Use in Reports
|
||||
|
||||
After 24-48 hours:
|
||||
|
||||
1. Analytics → Reports → Explorations
|
||||
2. Create Free-form Exploration
|
||||
3. Drag dimensions and metrics to canvas
|
||||
4. Add "Video Duration (seconds)" metric
|
||||
5. Analyze average, sum, or other aggregations
|
||||
|
||||
**Example Report:**
|
||||
|
||||
```
|
||||
Video Title Average Duration Total Views
|
||||
====================================================
|
||||
GA4 Basics 900 seconds 250
|
||||
Advanced Analytics 1800 seconds 180
|
||||
Debugging Guide 450 seconds 320
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Calculated Metrics
|
||||
|
||||
### What Are Calculated Metrics?
|
||||
|
||||
Calculated metrics are derived metrics created from mathematical formulas using existing metrics. They don't require new event implementation - only calculation.
|
||||
|
||||
**Use calculated metrics for:**
|
||||
- Ratios (revenue per user, conversion rate)
|
||||
- Differences (abandonment = views - purchases)
|
||||
- Complex formulas (LTV, efficiency scores)
|
||||
- Normalized metrics (revenue per session)
|
||||
|
||||
### Calculated Metric Examples
|
||||
|
||||
**Example 1: Revenue Per User**
|
||||
|
||||
```
|
||||
Name: Revenue per User
|
||||
Formula: revenue / users
|
||||
Result: Shows how much revenue each user generates
|
||||
```
|
||||
|
||||
**Example 2: Conversion Rate**
|
||||
|
||||
```
|
||||
Name: Conversion Rate %
|
||||
Formula: (conversions / sessions) * 100
|
||||
Result: Percentage of sessions with conversion
|
||||
```
|
||||
|
||||
**Example 3: Bounce Rate (Inverse)**
|
||||
|
||||
```
|
||||
Name: Engagement Rate
|
||||
Formula: (engagedSessions / sessions) * 100
|
||||
Result: Percentage of engaged sessions
|
||||
```
|
||||
|
||||
**Example 4: Add-to-Cart Rate**
|
||||
|
||||
```
|
||||
Name: Add to Cart Rate
|
||||
Formula: add_to_cart / view_item
|
||||
Result: How many cart adds vs product views
|
||||
```
|
||||
|
||||
**Example 5: Revenue Per Customer**
|
||||
|
||||
```
|
||||
Name: Average Order Value
|
||||
Formula: totalRevenue / transactions
|
||||
Result: Average amount per transaction
|
||||
```
|
||||
|
||||
### Available Metrics in Formulas
|
||||
|
||||
Standard GA4 metrics available for calculated metrics:
|
||||
|
||||
**User Metrics:**
|
||||
- `users` - Total unique users
|
||||
- `newUsers` - First-time users
|
||||
- `activeUsers` - Users with engagement/conversion
|
||||
|
||||
**Session Metrics:**
|
||||
- `sessions` - Total sessions
|
||||
- `sessionsPerUser` - Average sessions per user
|
||||
- `engagementRate` - Engaged sessions percentage
|
||||
|
||||
**Event Metrics:**
|
||||
- `eventCount` - Total events
|
||||
- `engagements` - Engaged sessions
|
||||
- `engagementDuration` - Total engagement time seconds
|
||||
|
||||
**Conversion Metrics:**
|
||||
- `conversions` - Key event count
|
||||
- `conversionValue` - Total key event value
|
||||
|
||||
**Ecommerce Metrics:**
|
||||
- `purchaseRevenue` - Total revenue
|
||||
- `transactions` - Number of purchases
|
||||
- `itemsViewed` - Total products viewed
|
||||
- `itemsPurchased` - Total items sold
|
||||
|
||||
**Custom Metrics:**
|
||||
- Any custom metric created
|
||||
|
||||
### Calculated Metric Formula Syntax
|
||||
|
||||
**Basic Operators:**
|
||||
|
||||
```
|
||||
Addition: metric1 + metric2
|
||||
Subtraction: metric1 - metric2
|
||||
Multiplication: metric1 * metric2
|
||||
Division: metric1 / metric2
|
||||
Parentheses: (metric1 + metric2) / metric3
|
||||
```
|
||||
|
||||
**Example Formulas:**
|
||||
|
||||
```
|
||||
// Simple division
|
||||
revenue / users
|
||||
|
||||
// Multiplication
|
||||
revenue * 100
|
||||
|
||||
// Complex formula with parentheses
|
||||
(conversions / sessions) * 100
|
||||
|
||||
// Multi-step calculation
|
||||
(purchaseRevenue - cost) / transactions
|
||||
|
||||
// Using custom metrics
|
||||
custom_metric_1 / custom_metric_2
|
||||
```
|
||||
|
||||
### Creating Calculated Metric: Step-by-Step
|
||||
|
||||
**Scenario: Create "Revenue Per Session" Metric**
|
||||
|
||||
1. Admin → Data Display → Custom Definitions
|
||||
|
||||
2. Click **"Create Custom Metric"** button
|
||||
|
||||
3. Fill form:
|
||||
|
||||
| Field | Entry |
|
||||
|-------|-------|
|
||||
| Metric Name | "Revenue per Session" |
|
||||
| Type | Select **Calculated** |
|
||||
| Formula | `revenue / sessions` |
|
||||
|
||||
4. Click **Save**
|
||||
|
||||
5. **Calculated metrics populate immediately** (no 24-48 hour wait)
|
||||
|
||||
6. Use in reports right away
|
||||
|
||||
### Using Calculated Metric in Reports
|
||||
|
||||
1. Analytics → Reports → Explorations
|
||||
2. Create Free-form Exploration
|
||||
3. Add dimensions
|
||||
4. Add metrics (including new calculated metric)
|
||||
5. View results
|
||||
|
||||
**Example Report Using "Revenue per Session":**
|
||||
|
||||
```
|
||||
Traffic Source Revenue per Session
|
||||
============================================
|
||||
google / organic $15.50
|
||||
direct / (none) $8.20
|
||||
facebook / referral $12.00
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Metric Type Comparison
|
||||
|
||||
### Standard Metrics vs Calculated Metrics
|
||||
|
||||
| Aspect | Standard | Calculated |
|
||||
|--------|----------|-----------|
|
||||
| Implementation | Requires event code | No code needed |
|
||||
| Delay | 24-48 hours | Immediate |
|
||||
| Data Source | Event parameters | Existing metrics |
|
||||
| Updates | As new events arrive | Real-time calculation |
|
||||
| Example | `video_duration` | `revenue / users` |
|
||||
| Quota | 50 per property | 5 per property |
|
||||
|
||||
### When to Use Each Type
|
||||
|
||||
**Use Standard Custom Metric when:**
|
||||
- Tracking new numerical data
|
||||
- Need to capture value at event time
|
||||
- Value must be sent from client/server
|
||||
|
||||
**Use Calculated Metric when:**
|
||||
- Combining existing metrics
|
||||
- Want ratio or percentage
|
||||
- Mathematical derivation from existing data
|
||||
|
||||
---
|
||||
|
||||
## Practical Custom Metrics Examples
|
||||
|
||||
### Example 1: Video Analytics Metrics
|
||||
|
||||
**Standard Custom Metrics:**
|
||||
|
||||
```javascript
|
||||
gtag('event', 'video_watched', {
|
||||
'video_title': 'GA4 101',
|
||||
'video_duration_seconds': 1200, // Custom metric
|
||||
'minutes_watched': 18, // Custom metric
|
||||
'completion_percentage': 85 // Custom metric
|
||||
});
|
||||
```
|
||||
|
||||
**Admin Registration:**
|
||||
1. Metric: "Video Duration (seconds)" = video_duration_seconds
|
||||
2. Metric: "Minutes Watched" = minutes_watched
|
||||
3. Metric: "Completion %" = completion_percentage
|
||||
|
||||
**Calculated Metrics:**
|
||||
|
||||
```
|
||||
Name: Video Watch Rate
|
||||
Formula: (minutes_watched / video_duration_seconds) * 100
|
||||
Result: Percentage of video watched
|
||||
```
|
||||
|
||||
### Example 2: SaaS Trial Conversion Metrics
|
||||
|
||||
**Standard Custom Metrics:**
|
||||
|
||||
```javascript
|
||||
gtag('event', 'trial_signup', {
|
||||
'trial_length_days': 14, // Custom metric
|
||||
'users_on_team': 3, // Custom metric
|
||||
'data_imported_count': 5 // Custom metric
|
||||
});
|
||||
|
||||
gtag('event', 'trial_to_paid', {
|
||||
'days_on_trial': 7, // Custom metric
|
||||
'upsell_offer_price': 99.99 // Custom metric
|
||||
});
|
||||
```
|
||||
|
||||
**Admin Registration:**
|
||||
- Metric: "Trial Length (days)"
|
||||
- Metric: "Team Size"
|
||||
- Metric: "Data Imported"
|
||||
- Metric: "Trial Duration (days)"
|
||||
- Metric: "Offer Price ($)"
|
||||
|
||||
**Calculated Metrics:**
|
||||
|
||||
```
|
||||
Name: Trial to Paid Rate
|
||||
Formula: trial_to_paid / trial_signup
|
||||
|
||||
Name: Average Trial Length
|
||||
Formula: trial_length_days / trial_signup
|
||||
|
||||
Name: Revenue per Trial
|
||||
Formula: (upsell_offer_price * trial_to_paid) / trial_signup
|
||||
```
|
||||
|
||||
### Example 3: E-commerce Metrics
|
||||
|
||||
**Standard Custom Metrics:**
|
||||
|
||||
```javascript
|
||||
gtag('event', 'purchase', {
|
||||
'transaction_id': 'TXN_123',
|
||||
'value': 299.99,
|
||||
'num_items': 3, // Custom metric
|
||||
'discount_amount': 30.00, // Custom metric
|
||||
'profit_margin': 0.40 // Custom metric
|
||||
});
|
||||
```
|
||||
|
||||
**Admin Registration:**
|
||||
- Metric: "Items per Order"
|
||||
- Metric: "Discount Amount ($)"
|
||||
- Metric: "Profit Margin %"
|
||||
|
||||
**Calculated Metrics:**
|
||||
|
||||
```
|
||||
Name: Average Item Price
|
||||
Formula: revenue / num_items
|
||||
|
||||
Name: Revenue After Discount
|
||||
Formula: revenue - discount_amount
|
||||
|
||||
Name: Gross Profit
|
||||
Formula: revenue * profit_margin
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Metric Limits & Quotas
|
||||
|
||||
### Standard GA4 Property Limits
|
||||
|
||||
- **Standard Custom Metrics:** 50 maximum
|
||||
- **Calculated Metrics:** 5 maximum
|
||||
- **Total available:** 50 standard + 5 calculated
|
||||
|
||||
### GA4 360 Property Limits
|
||||
|
||||
- **Standard Custom Metrics:** 125 maximum
|
||||
- **Calculated Metrics:** 50 maximum
|
||||
- **Total available:** 125 standard + 50 calculated
|
||||
|
||||
### Quota Management Strategy
|
||||
|
||||
**Prioritize metrics by importance:**
|
||||
|
||||
1. **Essential** (create immediately)
|
||||
- Key business KPIs
|
||||
- Required for dashboards
|
||||
- Regulatory/compliance metrics
|
||||
|
||||
2. **Important** (create if quota allows)
|
||||
- Nice-to-have analyses
|
||||
- Supporting metrics
|
||||
- Team requested metrics
|
||||
|
||||
3. **Nice-to-have** (create last)
|
||||
- Exploratory metrics
|
||||
- Lower priority analysis
|
||||
|
||||
---
|
||||
|
||||
## Best Practices for Custom Metrics
|
||||
|
||||
### Naming Conventions
|
||||
|
||||
**Good names:**
|
||||
- "Video Duration (seconds)"
|
||||
- "Form Fill Time (seconds)"
|
||||
- "Revenue per Session"
|
||||
- "Customer Lifetime Value ($)"
|
||||
- "Engagement Score"
|
||||
|
||||
**Poor names:**
|
||||
- "metric1"
|
||||
- "data"
|
||||
- "value"
|
||||
- "custom"
|
||||
|
||||
### Implementation Best Practices
|
||||
|
||||
**DO:**
|
||||
- ✅ Send as numbers, not strings
|
||||
- ✅ Use consistent units (always seconds, always dollars)
|
||||
- ✅ Document what each metric represents
|
||||
- ✅ Plan metrics before implementation
|
||||
- ✅ Register only metrics actually used
|
||||
- ✅ Include unit in metric name if applicable
|
||||
|
||||
**DON'T:**
|
||||
- ❌ Send metric as string ("120" instead of 120)
|
||||
- ❌ Mix units (seconds in one event, minutes in another)
|
||||
- ❌ Create too many similar metrics
|
||||
- ❌ Register metrics without team agreement
|
||||
- ❌ Use high-cardinality metrics (too many values)
|
||||
|
||||
### Metric Value Ranges
|
||||
|
||||
**Recommended ranges:**
|
||||
|
||||
- Quantities: 0-1000000
|
||||
- Percentages: 0-100
|
||||
- Monetary: -999999 to 999999
|
||||
- Time (seconds): 0-86400 (24 hours)
|
||||
- Ratings: 0-10 or 1-5
|
||||
|
||||
**Avoid:**
|
||||
- Negative values (usually)
|
||||
- Extreme outliers (data quality issues)
|
||||
- Non-numerical data (use dimensions instead)
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting Custom Metrics
|
||||
|
||||
### Metric Doesn't Appear in Reports After 48 Hours
|
||||
|
||||
**Troubleshooting:**
|
||||
|
||||
1. **Verify code sends numerical value**
|
||||
- Check DebugView
|
||||
- Value must be a number, not string
|
||||
- Example: 120 (not "120")
|
||||
|
||||
2. **Check metric name case**
|
||||
- DebugView shows exact case
|
||||
- Match exactly when registering
|
||||
|
||||
3. **Confirm quota not exceeded**
|
||||
- Standard metrics: Under 50?
|
||||
- Calculated metrics: Under 5?
|
||||
- Delete unused metrics if over quota
|
||||
|
||||
4. **Check minimum traffic threshold**
|
||||
- Events with metric need to fire
|
||||
- If no events: Metric won't populate
|
||||
- Verify code deployed and live
|
||||
|
||||
### Metric Shows Wrong Values
|
||||
|
||||
**Likely cause:** Parameter values not numbers
|
||||
|
||||
```javascript
|
||||
// WRONG - values are strings
|
||||
gtag('event', 'video_watched', {
|
||||
'duration': '120' // String
|
||||
});
|
||||
|
||||
// CORRECT - values are numbers
|
||||
gtag('event', 'video_watched', {
|
||||
'duration': 120 // Number
|
||||
});
|
||||
```
|
||||
|
||||
### Calculated Metric Formula Error
|
||||
|
||||
**Error message:** "Invalid formula syntax"
|
||||
|
||||
**Check:**
|
||||
- Metric names spelled correctly
|
||||
- Formula uses `/`, `*`, `+`, `-` only
|
||||
- Parentheses balanced
|
||||
- No special characters
|
||||
|
||||
```javascript
|
||||
// WRONG
|
||||
(revenue / users) + % // % not allowed
|
||||
|
||||
// CORRECT
|
||||
(revenue / users) * 100 // Use * 100 for percentage
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Advanced: Multi-Step Metrics
|
||||
|
||||
### Chain Calculations
|
||||
|
||||
Create multiple calculated metrics that build on each other:
|
||||
|
||||
**Step 1: Create basic metrics**
|
||||
- revenue / sessions = "Revenue per Session"
|
||||
|
||||
**Step 2: Create metrics using other calculated metrics**
|
||||
- revenue_per_session * users = "Revenue Per User"
|
||||
|
||||
**Metric Dependency Example:**
|
||||
|
||||
```
|
||||
Step 1: Sessions with Purchase = purchase_events (standard metric)
|
||||
|
||||
Step 2: Purchase Rate = purchase_events / sessions (calculated)
|
||||
|
||||
Step 3: Revenue Per Converting Session =
|
||||
revenue / purchase_events (calculated)
|
||||
|
||||
Step 4: Revenue Per All Sessions =
|
||||
revenue / sessions (calculated)
|
||||
```
|
||||
|
||||
### Using Custom Metrics in Audiences
|
||||
|
||||
Custom metrics can be used in audience conditions (GA4 360 only):
|
||||
|
||||
```
|
||||
Audience: "High-Value Customers"
|
||||
Condition: customer_lifetime_value > 1000 (custom metric)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Metric Comparison Reference
|
||||
|
||||
### All Available Metric Types
|
||||
|
||||
| Metric Type | Created How | Updated | Quota |
|
||||
|-------------|-----------|---------|-------|
|
||||
| Built-in | GA4 default | Real-time | N/A |
|
||||
| Standard Custom | Event code | After 24-48hrs | 50 |
|
||||
| Calculated | Formula | Real-time | 5 |
|
||||
|
||||
### Summary Table
|
||||
|
||||
| Scenario | Use This | Why |
|
||||
|----------|----------|-----|
|
||||
| Tracking video duration | Standard Custom Metric | Requires code implementation |
|
||||
| Calculating revenue/user | Calculated Metric | Derive from existing metrics |
|
||||
| Counting form submissions | Built-in (conversions) | Already exists |
|
||||
| Measuring engagement score | Calculated Metric | Formula from user_engagement |
|
||||
| Tracking items in cart | Standard Custom Metric | New event parameter needed |
|
||||
|
||||
@@ -0,0 +1,575 @@
|
||||
# GA4 Dimension Limits, Quotas & Planning Guide
|
||||
|
||||
## Standard GA4 Property Quotas
|
||||
|
||||
### Dimension Quotas
|
||||
|
||||
| Scope Type | Limit | GA4 360 Limit |
|
||||
|------------|-------|---------------|
|
||||
| Event-scoped custom dimensions | 50 | 125 |
|
||||
| User-scoped custom dimensions | 25 | 100 |
|
||||
| Item-scoped custom dimensions | 10 | 25 |
|
||||
|
||||
### Metric Quotas
|
||||
|
||||
| Metric Type | Limit | GA4 360 Limit |
|
||||
|-------------|-------|---------------|
|
||||
| Standard custom metrics | 50 | 125 |
|
||||
| Calculated metrics | 5 | 50 |
|
||||
|
||||
### Total Dimension Budget
|
||||
|
||||
**Standard GA4:**
|
||||
- Maximum total: 50 + 25 + 10 = 85 custom dimensions
|
||||
|
||||
**GA4 360:**
|
||||
- Maximum total: 125 + 100 + 25 = 250 custom dimensions
|
||||
|
||||
---
|
||||
|
||||
## Understanding Quota Impacts
|
||||
|
||||
### Event-Scoped Dimensions (50 Max in Standard GA4)
|
||||
|
||||
**Typical usage distribution:**
|
||||
|
||||
```
|
||||
High priority (essential): 5-10 dimensions
|
||||
Medium priority (important): 10-15 dimensions
|
||||
Low priority (nice-to-have): 5-10 dimensions
|
||||
Testing/experimental: 5-10 dimensions
|
||||
Unused/deprecated: 5-10 dimensions
|
||||
Total: 30-55 dimensions (likely over quota)
|
||||
```
|
||||
|
||||
### User-Scoped Dimensions (25 Max in Standard GA4)
|
||||
|
||||
**Typical usage distribution:**
|
||||
|
||||
```
|
||||
Subscription/plan tier: 1 dimension
|
||||
Customer segment: 1 dimension
|
||||
Account status: 1 dimension
|
||||
Company characteristics: 3-5 dimensions
|
||||
Behavioral attributes: 3-5 dimensions
|
||||
Preferences: 3-5 dimensions
|
||||
Unused/deprecated: 3-5 dimensions
|
||||
Total: 15-25 dimensions (likely at/near quota)
|
||||
```
|
||||
|
||||
### Item-Scoped Dimensions (10 Max in Standard GA4)
|
||||
|
||||
**Typical usage distribution:**
|
||||
|
||||
```
|
||||
Color/variant: 1-2 dimensions
|
||||
Size: 1 dimension
|
||||
Material/fabric: 1 dimension
|
||||
Supplier/vendor: 1 dimension
|
||||
Quality tier: 1 dimension
|
||||
Unused/test: 2-3 dimensions
|
||||
Total: 8-10 dimensions (likely at quota)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quota Management Strategy
|
||||
|
||||
### When You Hit Quota
|
||||
|
||||
**Immediate:**
|
||||
1. Stop creating new dimensions temporarily
|
||||
2. Audit existing dimensions for unused ones
|
||||
3. Delete low-priority/test dimensions
|
||||
4. Document deletions
|
||||
|
||||
**Medium-term:**
|
||||
1. Consolidate similar dimensions
|
||||
2. Archive less-used dimensions (delete then document)
|
||||
3. Consider GA4 360 upgrade if quota consistently exceeded
|
||||
|
||||
**Long-term:**
|
||||
1. Plan which dimensions are truly essential
|
||||
2. Establish dimension governance policies
|
||||
3. Regular quarterly reviews of dimension usage
|
||||
|
||||
### Prioritization Framework
|
||||
|
||||
**Tier 1: Keep (Essential)**
|
||||
- ✓ Required for critical business reports
|
||||
- ✓ Used by multiple teams
|
||||
- ✓ Part of regulatory/compliance reporting
|
||||
- ✓ Cannot be replaced by built-in dimensions
|
||||
|
||||
**Tier 2: Keep (Important)**
|
||||
- ✓ Used regularly in analysis
|
||||
- ✓ Part of team dashboards
|
||||
- ✓ Supports strategic decisions
|
||||
- ✓ Actively send data (not dormant)
|
||||
|
||||
**Tier 3: Review (Optional)**
|
||||
- ? Used occasionally
|
||||
- ? Experimental in nature
|
||||
- ? Data doesn't appear in reports
|
||||
- ? Can be replicated from other data
|
||||
|
||||
**Tier 4: Delete (Candidates)**
|
||||
- ✗ Never used in reports
|
||||
- ✗ Data not being sent (implementation missing)
|
||||
- ✗ Duplicate of existing dimension
|
||||
- ✗ Test/experimental dimension
|
||||
- ✗ Parameter no longer tracked
|
||||
|
||||
### Audit Checklist
|
||||
|
||||
Run quarterly to identify deletable dimensions:
|
||||
|
||||
```
|
||||
For each dimension, check:
|
||||
|
||||
[ ] Has data in reports?
|
||||
NO → Candidate for deletion
|
||||
|
||||
[ ] Used by any teams?
|
||||
NO → Candidate for deletion
|
||||
|
||||
[ ] Parameter still being sent?
|
||||
NO → Candidate for deletion
|
||||
|
||||
[ ] Duplicate of another dimension?
|
||||
YES → Delete duplicate
|
||||
|
||||
[ ] Actively analyzed?
|
||||
NO → Candidate for deletion
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Parameter Limits (Not Quota-Based)
|
||||
|
||||
These are separate from dimension quotas - they apply to all events:
|
||||
|
||||
### Event Parameter Limits
|
||||
|
||||
| Aspect | Limit | Notes |
|
||||
|--------|-------|-------|
|
||||
| Parameters per event | 25 max | Total count of all parameters |
|
||||
| Parameter name length | 40 characters | Cannot be longer |
|
||||
| String parameter value | 100 characters | Most parameters |
|
||||
| page_title value | 300 characters | Special exception |
|
||||
| page_referrer value | 420 characters | Special exception |
|
||||
| page_location value | 1000 characters | Special exception |
|
||||
|
||||
### Items Array Limits
|
||||
|
||||
| Aspect | Limit | Notes |
|
||||
|--------|-------|-------|
|
||||
| Items per event | 27 max | Maximum products in one transaction |
|
||||
| Item parameters | 10+ available | Predefined + custom |
|
||||
| Item parameter value | 100 characters | Standard limits apply |
|
||||
|
||||
### User Property Limits
|
||||
|
||||
| Aspect | Limit | Notes |
|
||||
|--------|-------|-------|
|
||||
| User properties per user | 100 max | Total count across all |
|
||||
| Property name length | 40 characters | Cannot be longer |
|
||||
| Property value length | 100 characters | Standard limits |
|
||||
|
||||
---
|
||||
|
||||
## Quota Warnings & Enforcement
|
||||
|
||||
### Before Hitting Quota
|
||||
|
||||
**GA4 provides warnings:**
|
||||
- No explicit warning currently (as of 2024)
|
||||
- Monitor quota usage in Admin → Custom Definitions
|
||||
- List shows all dimensions with counts
|
||||
|
||||
### When At Quota
|
||||
|
||||
**Behavior:**
|
||||
- Cannot create new dimension of that scope
|
||||
- Error message: Cannot proceed
|
||||
- Must delete existing dimension first
|
||||
|
||||
### When Over Quota (Impossible)
|
||||
|
||||
**By design:** GA4 prevents exceeding quota
|
||||
- Will not let you create if would exceed
|
||||
- Must delete first
|
||||
|
||||
---
|
||||
|
||||
## Capacity Planning Worksheet
|
||||
|
||||
Use this worksheet to plan dimensions before implementation:
|
||||
|
||||
### Event-Scoped Dimensions Planning
|
||||
|
||||
```
|
||||
Total quota: 50 (Standard GA4) / 125 (GA4 360)
|
||||
|
||||
Category 1: Form Tracking
|
||||
[ ] form_name
|
||||
[ ] form_id
|
||||
[ ] form_type
|
||||
Subtotal: 3
|
||||
|
||||
Category 2: Button/Link Tracking
|
||||
[ ] button_name
|
||||
[ ] link_destination
|
||||
[ ] link_type
|
||||
Subtotal: 3
|
||||
|
||||
Category 3: Video Tracking
|
||||
[ ] video_title
|
||||
[ ] video_quality
|
||||
[ ] video_category
|
||||
Subtotal: 3
|
||||
|
||||
Category 4: Error Tracking
|
||||
[ ] error_type
|
||||
[ ] error_code
|
||||
Subtotal: 2
|
||||
|
||||
Category 5: [Your Category]
|
||||
[ ] dimension_name
|
||||
Subtotal: X
|
||||
|
||||
TOTAL PLANNED: 11+ dimensions
|
||||
QUOTA AVAILABLE: 50
|
||||
BUFFER REMAINING: 39
|
||||
```
|
||||
|
||||
### User-Scoped Dimensions Planning
|
||||
|
||||
```
|
||||
Total quota: 25 (Standard GA4) / 100 (GA4 360)
|
||||
|
||||
Category 1: Subscription/Tier
|
||||
[ ] subscription_tier
|
||||
[ ] trial_status
|
||||
Subtotal: 2
|
||||
|
||||
Category 2: Customer Type
|
||||
[ ] customer_segment
|
||||
[ ] customer_type
|
||||
Subtotal: 2
|
||||
|
||||
Category 3: Account Status
|
||||
[ ] account_status
|
||||
[ ] account_age
|
||||
Subtotal: 2
|
||||
|
||||
Category 4: Company Information
|
||||
[ ] company_size
|
||||
[ ] industry
|
||||
[ ] company_country
|
||||
Subtotal: 3
|
||||
|
||||
Category 5: Preferences
|
||||
[ ] preferred_language
|
||||
[ ] communication_preference
|
||||
Subtotal: 2
|
||||
|
||||
Category 6: [Your Category]
|
||||
[ ] property_name
|
||||
Subtotal: X
|
||||
|
||||
TOTAL PLANNED: 11+ dimensions
|
||||
QUOTA AVAILABLE: 25
|
||||
BUFFER REMAINING: 14
|
||||
```
|
||||
|
||||
### Item-Scoped Dimensions Planning
|
||||
|
||||
```
|
||||
Total quota: 10 (Standard GA4) / 25 (GA4 360)
|
||||
|
||||
Category 1: Product Attributes
|
||||
[ ] item_color
|
||||
[ ] item_size
|
||||
Subtotal: 2
|
||||
|
||||
Category 2: Supplier/Source
|
||||
[ ] supplier
|
||||
[ ] warehouse_location
|
||||
Subtotal: 2
|
||||
|
||||
Category 3: Product Quality
|
||||
[ ] quality_tier
|
||||
Subtotal: 1
|
||||
|
||||
Category 4: [Your Category]
|
||||
[ ] property_name
|
||||
Subtotal: X
|
||||
|
||||
TOTAL PLANNED: 5+ dimensions
|
||||
QUOTA AVAILABLE: 10
|
||||
BUFFER REMAINING: 5
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Optimization Strategies
|
||||
|
||||
### Strategy 1: Consolidation
|
||||
|
||||
**Instead of:** 3 separate dimensions (button_text, button_id, button_type)
|
||||
|
||||
**Use:** 1 dimension (button_identifier = "type_id_text")
|
||||
|
||||
**Benefit:** Saves 2 dimensions, still trackable
|
||||
|
||||
### Strategy 2: Hierarchy Reduction
|
||||
|
||||
**Instead of:** item_category, item_subcategory, item_subsubcategory (3 dimensions)
|
||||
|
||||
**Use:** Built-in item_category (predefined) + custom item_category2 (predefined)
|
||||
|
||||
**Benefit:** Saves 1 dimension using pre-built fields
|
||||
|
||||
### Strategy 3: Metric instead of Dimension
|
||||
|
||||
**Instead of:** Dimension "video_watch_percentage"
|
||||
|
||||
**Use:** Metric minutes_watched (numeric) + Formula
|
||||
|
||||
**Benefit:** Dimensions for categorization, metrics for calculation
|
||||
|
||||
### Strategy 4: Segment in Exploration
|
||||
|
||||
**Instead of:** User-scoped dimension "cohort_type"
|
||||
|
||||
**Use:** Build temporary segment in Exploration for analysis
|
||||
|
||||
**Benefit:** Saves dimension quota, still enables analysis
|
||||
|
||||
---
|
||||
|
||||
## GA4 360 Considerations
|
||||
|
||||
### When to Upgrade to GA4 360
|
||||
|
||||
**Quota benefits:**
|
||||
- 2.5x more event-scoped dimensions (50 → 125)
|
||||
- 4x more user-scoped dimensions (25 → 100)
|
||||
- 2.5x more item-scoped dimensions (10 → 25)
|
||||
|
||||
**Other GA4 360 benefits:**
|
||||
- Increased custom metric quotas
|
||||
- Extended data retention (up to 50 months)
|
||||
- Advanced features (data-driven attribution by default)
|
||||
- Data import capabilities
|
||||
- Streaming BigQuery export
|
||||
- Advanced support
|
||||
|
||||
**When quota-only upgrade makes sense:**
|
||||
- More than 85 total dimensions needed
|
||||
- Multiple teams each needing own dimensions
|
||||
- Complex ecommerce tracking (20+ item attributes)
|
||||
- Enterprise with many business units
|
||||
|
||||
---
|
||||
|
||||
## Common Quota Mistakes to Avoid
|
||||
|
||||
### Mistake 1: Creating Similar Dimensions
|
||||
|
||||
```
|
||||
❌ WRONG:
|
||||
- button_name
|
||||
- button_text
|
||||
- button_label
|
||||
(These are the same thing!)
|
||||
|
||||
✓ CORRECT:
|
||||
- button_name
|
||||
(Use consistently)
|
||||
```
|
||||
|
||||
**Prevention:** Establish naming standards before implementation
|
||||
|
||||
### Mistake 2: Creating Dimensions for Unique Values
|
||||
|
||||
```
|
||||
❌ WRONG:
|
||||
- user_email (millions of unique values)
|
||||
- session_id (unique per session)
|
||||
- timestamp (continuous values)
|
||||
(High cardinality, not useful for analysis)
|
||||
|
||||
✓ CORRECT:
|
||||
- user_tier (few values)
|
||||
- user_region (manageable values)
|
||||
- signup_month (grouped time)
|
||||
```
|
||||
|
||||
**Prevention:** Only dimensions with <100 unique values
|
||||
|
||||
### Mistake 3: Not Deleting Test Dimensions
|
||||
|
||||
```
|
||||
❌ WRONG:
|
||||
- test_dimension
|
||||
- temp_parameter
|
||||
- dev_test
|
||||
- debugging_param
|
||||
(Wastes quota)
|
||||
|
||||
✓ CORRECT:
|
||||
- Delete test dimensions after verification
|
||||
- Use separate test GA4 property
|
||||
```
|
||||
|
||||
**Prevention:** Track test vs. production dimensions
|
||||
|
||||
### Mistake 4: Creating Redundant Dimensions
|
||||
|
||||
```
|
||||
❌ WRONG:
|
||||
- page_title (already built-in!)
|
||||
- device_category (already built-in!)
|
||||
- user_id (use User ID feature instead)
|
||||
|
||||
✓ CORRECT:
|
||||
- Review built-in dimensions first
|
||||
- Only create custom when necessary
|
||||
```
|
||||
|
||||
**Prevention:** Audit built-in dimensions before creating custom
|
||||
|
||||
---
|
||||
|
||||
## Quota Governance Policy (Template)
|
||||
|
||||
Organizations should establish policies:
|
||||
|
||||
### Dimension Creation Policy
|
||||
|
||||
**Before Creation:**
|
||||
1. Business justification required
|
||||
2. Dimensions reviewed by analytics lead
|
||||
3. Check if built-in dimension exists
|
||||
4. Verify quota available
|
||||
5. Document in shared list
|
||||
|
||||
**After Creation:**
|
||||
1. Register properly (scope, naming)
|
||||
2. Implement in code
|
||||
3. Verify in DebugView
|
||||
4. Document in team wiki
|
||||
5. Add to dashboard/report
|
||||
|
||||
### Dimension Review Schedule
|
||||
|
||||
**Quarterly Review (Every 3 months):**
|
||||
1. List all custom dimensions
|
||||
2. Check which have data
|
||||
3. Check which are used
|
||||
4. Mark for deletion if unused
|
||||
5. Archive documentation
|
||||
|
||||
**Annual Audit (Every 12 months):**
|
||||
1. Complete dimensions review
|
||||
2. Consolidation opportunities
|
||||
3. Quota forecasting
|
||||
4. GA4 360 evaluation
|
||||
5. Update governance policy
|
||||
|
||||
### Naming Standards
|
||||
|
||||
**All Event-Scoped Dimensions:**
|
||||
- Format: `[action]_[object]`
|
||||
- Examples: `button_name`, `form_id`, `video_title`
|
||||
|
||||
**All User-Scoped Dimensions:**
|
||||
- Format: `[attribute]` or `user_[attribute]`
|
||||
- Examples: `subscription_tier`, `customer_segment`
|
||||
|
||||
**All Item-Scoped Dimensions:**
|
||||
- Format: `item_[attribute]`
|
||||
- Examples: `item_color`, `item_size`
|
||||
|
||||
---
|
||||
|
||||
## Quota Tracking Template
|
||||
|
||||
Keep this updated to monitor quota usage:
|
||||
|
||||
### Event-Scoped Tracking
|
||||
|
||||
```
|
||||
Date: 2024-11-10
|
||||
Total Created: 35 / 50
|
||||
|
||||
High Priority (Keep):
|
||||
- form_name (active)
|
||||
- button_name (active)
|
||||
- error_type (active)
|
||||
- page_section (active)
|
||||
Subtotal: 4
|
||||
|
||||
Medium Priority (Keep):
|
||||
- video_title (light use)
|
||||
- link_type (monthly analysis)
|
||||
Subtotal: 2
|
||||
|
||||
Low Priority (Review):
|
||||
- test_param (no data)
|
||||
- old_tracking (deprecated)
|
||||
- experimental_dimension (unused)
|
||||
Subtotal: 3
|
||||
|
||||
Deletion Candidates: 3
|
||||
Recommended Action: Delete 3, keep 32
|
||||
|
||||
Next Review: 2025-02-10 (Quarterly)
|
||||
```
|
||||
|
||||
### User-Scoped Tracking
|
||||
|
||||
```
|
||||
Date: 2024-11-10
|
||||
Total Created: 22 / 25
|
||||
|
||||
In Use:
|
||||
- subscription_tier (critical)
|
||||
- customer_segment (critical)
|
||||
- account_status (important)
|
||||
- company_size (important)
|
||||
- industry (important)
|
||||
- preferred_language (used)
|
||||
- loyalty_status (used)
|
||||
Subtotal: 7
|
||||
|
||||
Unused/Deprecated:
|
||||
- old_tier_system (no data)
|
||||
- test_property (testing only)
|
||||
Subtotal: 2
|
||||
|
||||
Buffer Remaining: 3
|
||||
Recommendation: Delete old_tier_system, keep others
|
||||
|
||||
Next Review: 2025-02-10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Summary: Quick Decision Matrix
|
||||
|
||||
**Need to create a custom dimension? Use this:**
|
||||
|
||||
| Question | Yes | No |
|
||||
|----------|-----|-----|
|
||||
| Is it essential for business reporting? | Keep | Consider deletion |
|
||||
| Is there a built-in dimension for this? | Use built-in | Create custom |
|
||||
| Is there quota available? | Create | Delete other first |
|
||||
| Will it have <100 unique values? | Proceed | Rethink approach |
|
||||
| Is it for event-specific context? | Event scope | Use different scope |
|
||||
| Is it for all user events? | User scope | Use different scope |
|
||||
| Is it for products? | Item scope | Use different scope |
|
||||
| Do we have team consensus? | Create | Get approval first |
|
||||
|
||||
@@ -0,0 +1,524 @@
|
||||
# Complete Dimension Registration Walkthrough
|
||||
|
||||
## Pre-Registration Checklist
|
||||
|
||||
Before registering a custom dimension in GA4 Admin:
|
||||
|
||||
- [ ] Parameter is being sent in event code
|
||||
- [ ] Parameter name is finalized (case-sensitive)
|
||||
- [ ] Scope is determined (event/user/item)
|
||||
- [ ] Parameter verified in DebugView
|
||||
- [ ] Dimension name is approved by team
|
||||
- [ ] Not exceeding quota for scope type
|
||||
|
||||
---
|
||||
|
||||
## Method 1: Event-Scoped Dimension Registration
|
||||
|
||||
### Scenario: Tracking Which Forms Users Submit
|
||||
|
||||
**Step 1: Implement in Code**
|
||||
|
||||
Place the custom parameter in gtag event:
|
||||
|
||||
```javascript
|
||||
// On form submission
|
||||
document.getElementById('contact-form').addEventListener('submit', function() {
|
||||
gtag('event', 'form_submit', {
|
||||
'form_name': 'Contact Form',
|
||||
'form_id': 'contact-form-v1',
|
||||
'form_destination': '/thank-you'
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Step 2: Verify in DebugView
|
||||
|
||||
1. Open GA4 property → Admin → DebugView
|
||||
2. Install Google Analytics Debugger Chrome extension (if not installed)
|
||||
3. Enable the extension (click icon, ensure enabled)
|
||||
4. Refresh website page
|
||||
5. Perform action that triggers event (submit form)
|
||||
6. In DebugView left panel, click the "form_submit" event
|
||||
7. Expand event details on right panel
|
||||
8. Verify "form_name" parameter appears with correct value
|
||||
|
||||
**Expected DebugView Output:**
|
||||
|
||||
```
|
||||
Event: form_submit
|
||||
Timestamp: 2024-11-10 10:30:45.123
|
||||
|
||||
Parameters:
|
||||
- form_name: "Contact Form"
|
||||
- form_id: "contact-form-v1"
|
||||
- form_destination: "/thank-you"
|
||||
- (other auto-collected parameters)
|
||||
```
|
||||
|
||||
### Step 3: Navigate to Custom Definitions
|
||||
|
||||
1. In GA4 property interface, click **Admin** (bottom left)
|
||||
2. Under "Data Display" section, click **Custom Definitions**
|
||||
|
||||
### Step 4: Create Custom Dimension
|
||||
|
||||
1. Click **"Create Custom Dimension"** button (blue button, top right)
|
||||
2. Fill the form that appears:
|
||||
|
||||
| Field | Entry | Example |
|
||||
|-------|-------|---------|
|
||||
| Dimension Name | Human-friendly name (appears in reports) | "Form Name" |
|
||||
| Scope | Select "Event" | Event |
|
||||
| Event Parameter | Exact parameter name from code (case-sensitive) | form_name |
|
||||
| Description | Optional explanation | "Name of form submitted" |
|
||||
|
||||
3. Click **Save** button
|
||||
|
||||
### Step 5: Wait 24-48 Hours
|
||||
|
||||
- First 24 hours: DebugView may show parameter (if debug mode enabled)
|
||||
- 24-48 hours: Reports begin showing dimension
|
||||
- Retroactive population: Previous events reprocessed with dimension
|
||||
|
||||
### Step 6: Verify in Reports
|
||||
|
||||
After 24-48 hours:
|
||||
|
||||
1. Go to Analytics → Reports → any report
|
||||
2. Click **+ Customize** or **+ Add dimension**
|
||||
3. Search for "Form Name"
|
||||
4. Add to report
|
||||
5. Dimension values appear in data
|
||||
|
||||
---
|
||||
|
||||
## Method 2: User-Scoped Dimension Registration
|
||||
|
||||
### Scenario: Tracking Customer Subscription Tier
|
||||
|
||||
**Step 1: Implement in Code**
|
||||
|
||||
Set user property after user authentication:
|
||||
|
||||
```javascript
|
||||
// After successful login
|
||||
function handleLoginSuccess(user) {
|
||||
gtag('set', {
|
||||
'subscription_tier': user.planType, // 'free', 'pro', 'enterprise'
|
||||
'customer_id': user.id,
|
||||
'account_created_date': user.createdDate
|
||||
});
|
||||
|
||||
gtag('event', 'login', {
|
||||
'method': 'email'
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
**Important:** Set user properties BEFORE sending events to ensure properties apply to all events.
|
||||
|
||||
### Step 2: Verify in DebugView
|
||||
|
||||
1. GA4 property → Admin → DebugView
|
||||
2. Click any event after login (page_view, button_click, etc.)
|
||||
3. Expand event details
|
||||
4. Scroll to "User properties" section
|
||||
5. Verify "subscription_tier" appears with correct value
|
||||
|
||||
**Expected DebugView Output:**
|
||||
|
||||
```
|
||||
Event: page_view
|
||||
|
||||
User properties:
|
||||
- subscription_tier: "pro"
|
||||
- customer_id: "CUST_12345"
|
||||
- account_created_date: "2020-05-15"
|
||||
```
|
||||
|
||||
### Step 3: Navigate to Custom Definitions
|
||||
|
||||
1. Click **Admin** → **Custom Definitions**
|
||||
|
||||
### Step 4: Create Custom Dimension
|
||||
|
||||
1. Click **"Create Custom Dimension"**
|
||||
2. Fill the form:
|
||||
|
||||
| Field | Entry | Example |
|
||||
|-------|-------|---------|
|
||||
| Dimension Name | Human-friendly name | "Subscription Tier" |
|
||||
| Scope | Select "User" | User |
|
||||
| User Property | Exact property name from code | subscription_tier |
|
||||
| Description | Optional | "Customer's plan type" |
|
||||
|
||||
3. Click **Save**
|
||||
|
||||
### Step 5: Wait 24-48 Hours
|
||||
|
||||
Same as event-scoped dimensions.
|
||||
|
||||
### Step 6: Verify in Reports
|
||||
|
||||
After 24-48 hours:
|
||||
|
||||
1. Analytics → Reports
|
||||
2. Add dimension "Subscription Tier"
|
||||
3. See all events grouped by subscription tier
|
||||
|
||||
---
|
||||
|
||||
## Method 3: Item-Scoped Dimension Registration
|
||||
|
||||
### Scenario: Tracking Product Colors in Purchases
|
||||
|
||||
**Step 1: Implement in Code**
|
||||
|
||||
Place parameter in items array of ecommerce event:
|
||||
|
||||
```javascript
|
||||
gtag('event', 'purchase', {
|
||||
'transaction_id': 'TXN_' + Math.random(),
|
||||
'value': 149.98,
|
||||
'currency': 'USD',
|
||||
'items': [
|
||||
{
|
||||
'item_id': 'SKU_SHIRT_BLUE',
|
||||
'item_name': 'Blue T-Shirt',
|
||||
'price': 29.99,
|
||||
'quantity': 2,
|
||||
'item_category': 'Apparel',
|
||||
'item_color': 'blue' // CUSTOM DIMENSION
|
||||
},
|
||||
{
|
||||
'item_id': 'SKU_PANTS_BLACK',
|
||||
'item_name': 'Black Pants',
|
||||
'price': 49.99,
|
||||
'quantity': 1,
|
||||
'item_category': 'Apparel',
|
||||
'item_color': 'black' // CUSTOM DIMENSION - DIFFERENT VALUE
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
### Step 2: Verify in DebugView
|
||||
|
||||
1. GA4 property → Admin → DebugView
|
||||
2. Find "purchase" event
|
||||
3. Click to expand event details
|
||||
4. Scroll to "Items" section
|
||||
5. Verify each item shows "item_color" parameter
|
||||
|
||||
**Expected DebugView Output:**
|
||||
|
||||
```
|
||||
Event: purchase
|
||||
|
||||
Items:
|
||||
[0]:
|
||||
- item_id: "SKU_SHIRT_BLUE"
|
||||
- item_name: "Blue T-Shirt"
|
||||
- item_color: "blue"
|
||||
[1]:
|
||||
- item_id: "SKU_PANTS_BLACK"
|
||||
- item_name: "Black Pants"
|
||||
- item_color: "black"
|
||||
```
|
||||
|
||||
### Step 3: Navigate to Custom Definitions
|
||||
|
||||
1. Click **Admin** → **Custom Definitions**
|
||||
|
||||
### Step 4: Create Custom Dimension
|
||||
|
||||
1. Click **"Create Custom Dimension"**
|
||||
2. Fill the form:
|
||||
|
||||
| Field | Entry | Example |
|
||||
|-------|-------|---------|
|
||||
| Dimension Name | Human-friendly name | "Item Color" |
|
||||
| Scope | Select "Item" | Item |
|
||||
| Event Parameter | Parameter name from items array | item_color |
|
||||
| Description | Optional | "Color variant of product" |
|
||||
|
||||
3. Click **Save**
|
||||
|
||||
### Step 5: Wait 24-48 Hours
|
||||
|
||||
Same delay as other scope types.
|
||||
|
||||
### Step 6: Verify in Reports
|
||||
|
||||
After 24-48 hours:
|
||||
|
||||
1. Analytics → Reports → Monetization → Items
|
||||
2. Items report shows "Item Color" dimension
|
||||
3. Analyze which colors have best revenue, quantity, etc.
|
||||
|
||||
---
|
||||
|
||||
## Custom Dimension Registration Form - Field Reference
|
||||
|
||||
### Dimension Name Field
|
||||
|
||||
**What to enter:** Human-friendly name that will appear in reports and UI
|
||||
|
||||
**Best practices:**
|
||||
- Descriptive (not "custom1" or "data")
|
||||
- Title case ("Form Name", not "form name")
|
||||
- Under 50 characters
|
||||
- No special characters (use underscores if needed)
|
||||
- Avoid jargon unfamiliar to team
|
||||
|
||||
**Good examples:**
|
||||
- "Form Name"
|
||||
- "Video Quality"
|
||||
- "Customer Segment"
|
||||
- "Item Color"
|
||||
- "Error Type"
|
||||
|
||||
**Poor examples:**
|
||||
- "custom_param_1"
|
||||
- "data"
|
||||
- "x"
|
||||
- "param123"
|
||||
|
||||
### Scope Field
|
||||
|
||||
**What to select:**
|
||||
|
||||
Three radio button options:
|
||||
|
||||
1. **Event** - Single event occurrence
|
||||
- Use for event-specific context
|
||||
- Each event sends its own value
|
||||
- Examples: button_name, form_id, video_title
|
||||
|
||||
2. **User** - All user events
|
||||
- Use for user attributes
|
||||
- Set once, applies to all events
|
||||
- Examples: subscription_tier, customer_segment
|
||||
|
||||
3. **Item** - Products in ecommerce events
|
||||
- Use for product-level data
|
||||
- Goes in items array
|
||||
- Examples: item_color, item_size
|
||||
|
||||
**Cannot be changed after creation** - Choose carefully.
|
||||
|
||||
### Event Parameter / User Property Field
|
||||
|
||||
**What to enter:** Exact parameter or property name from code
|
||||
|
||||
**Critical requirements:**
|
||||
- Case-sensitive (subscription_tier ≠ subscription_Tier)
|
||||
- Must match exactly as sent in code
|
||||
- No spaces or special characters (use underscores)
|
||||
- Under 40 characters
|
||||
|
||||
**How to find exact name:**
|
||||
|
||||
1. Look at DebugView parameter/property name
|
||||
2. Copy parameter name exactly
|
||||
3. Paste into this field
|
||||
|
||||
**Example matching:**
|
||||
|
||||
Code sends:
|
||||
```javascript
|
||||
gtag('event', 'video_watch', {
|
||||
'video_quality': 'hd'
|
||||
});
|
||||
```
|
||||
|
||||
Registration field should contain:
|
||||
```
|
||||
video_quality
|
||||
```
|
||||
|
||||
NOT: "Video Quality" (that's the dimension name), "video_Quality", or "videoQuality"
|
||||
|
||||
### Description Field (Optional)
|
||||
|
||||
**What to enter:** Brief explanation of what dimension tracks
|
||||
|
||||
**Good descriptions:**
|
||||
- "Quality setting of video watched (hd, sd, auto)"
|
||||
- "Customer's plan type (free, pro, enterprise)"
|
||||
- "Color variant of product in purchase"
|
||||
- "Name of form submitted (contact, newsletter, demo)"
|
||||
|
||||
**Poor descriptions:**
|
||||
- "custom data"
|
||||
- "info"
|
||||
- "tracking"
|
||||
|
||||
---
|
||||
|
||||
## Post-Registration Verification Workflow
|
||||
|
||||
### Hour 0-6: Immediate Post-Registration
|
||||
|
||||
1. **Do NOT create duplicate dimension** while waiting
|
||||
2. **Do NOT modify the custom definition** (requires deletion and recreation)
|
||||
3. **Continue sending parameter** in events (essential for population)
|
||||
|
||||
### Hour 24: First 24-Hour Check
|
||||
|
||||
1. Go to DebugView
|
||||
2. Verify current events still sending parameter
|
||||
3. Check if any data appearing in reports (may show before 48 hours)
|
||||
4. Do NOT assume failure if not visible yet
|
||||
|
||||
### Hour 48: Full Population Expected
|
||||
|
||||
1. Go to Analytics → Reports
|
||||
2. Add custom dimension to any report
|
||||
3. If dimension appears: SUCCESS
|
||||
4. If dimension doesn't appear: Troubleshoot
|
||||
|
||||
### Verification Checklist
|
||||
|
||||
- [ ] Dimension appears in dimension picker (Admin → Custom Definitions)
|
||||
- [ ] Current events show dimension values in DebugView
|
||||
- [ ] After 48 hours, dimension appears in reports
|
||||
- [ ] Dimension values are accurate
|
||||
- [ ] No duplicate dimensions created by mistake
|
||||
|
||||
---
|
||||
|
||||
## Editing & Deleting Custom Dimensions
|
||||
|
||||
### Edit Custom Dimension
|
||||
|
||||
**Cannot directly edit.** To change dimension:
|
||||
|
||||
1. Note dimension settings (name, scope, parameter)
|
||||
2. Delete existing dimension
|
||||
3. Create new dimension with updated settings
|
||||
4. Wait 24-48 hours for new data population
|
||||
|
||||
**Why limited edits?**
|
||||
- Scope cannot change (event to user, etc.)
|
||||
- Parameter name essentially permanent
|
||||
- Dimension name can be edited, but best practices say don't
|
||||
|
||||
### Delete Custom Dimension
|
||||
|
||||
**When to delete:**
|
||||
- No longer tracking that parameter
|
||||
- Exceeding quota limits
|
||||
- Created by mistake
|
||||
- Need to recreate with different settings
|
||||
|
||||
**Process:**
|
||||
|
||||
1. Admin → Custom Definitions
|
||||
2. Find dimension in list
|
||||
3. Click the dimension name
|
||||
4. Click **Delete** button
|
||||
5. Confirm deletion
|
||||
|
||||
**After deletion:**
|
||||
- Historical data remains in reports (for 2-14 months per retention)
|
||||
- New dimension can be created with same parameter name
|
||||
- Takes 24-48 hours to remove from dimension picker
|
||||
|
||||
**Do NOT delete and immediately recreate** - Wait 24 hours to avoid conflicts.
|
||||
|
||||
---
|
||||
|
||||
## Batch Registration Strategy
|
||||
|
||||
When registering many dimensions at once:
|
||||
|
||||
### Prioritize by Quota
|
||||
|
||||
Standard GA4 limits:
|
||||
- Event-scoped: 50 max
|
||||
- User-scoped: 25 max
|
||||
- Item-scoped: 10 max
|
||||
|
||||
Prioritize:
|
||||
1. Essential for business reporting (register first)
|
||||
2. Important but not critical (register second)
|
||||
3. Nice-to-have (register if quota allows)
|
||||
|
||||
### Register in Waves
|
||||
|
||||
**Wave 1 (First): High-Priority Dimensions**
|
||||
- Register 5-10 critical dimensions
|
||||
- Wait 24-48 hours for population
|
||||
- Verify data accuracy
|
||||
|
||||
**Wave 2 (Later): Medium-Priority Dimensions**
|
||||
- Register after Wave 1 verified
|
||||
- Again wait 24-48 hours
|
||||
- Continue verification
|
||||
|
||||
**Wave 3 (Much Later): Low-Priority Dimensions**
|
||||
- Register final wave if quota allows
|
||||
- Ensure no conflicts with existing
|
||||
|
||||
### Why Wave Registration?
|
||||
|
||||
- Easier troubleshooting (fewer variables)
|
||||
- Confirm code quality before scale
|
||||
- Verify team understands process
|
||||
- Catch quota issues early
|
||||
|
||||
---
|
||||
|
||||
## Common Registration Issues & Solutions
|
||||
|
||||
### Dimension Doesn't Appear After 48 Hours
|
||||
|
||||
**Troubleshooting steps:**
|
||||
|
||||
1. **Verify code still sending parameter**
|
||||
- Check DebugView
|
||||
- Confirm events have parameter
|
||||
- If missing: Fix code implementation
|
||||
|
||||
2. **Check parameter name case-sensitivity**
|
||||
- Go to DebugView
|
||||
- Look at exact parameter name shown
|
||||
- Compare to registered parameter name
|
||||
- Must be EXACT match
|
||||
|
||||
3. **Confirm scope is correct**
|
||||
- Go to Admin → Custom Definitions
|
||||
- Check scope: Event, User, or Item?
|
||||
- Verify matches implementation
|
||||
|
||||
4. **Check quota not exceeded**
|
||||
- Event-scoped: Are you over 50?
|
||||
- User-scoped: Are you over 25?
|
||||
- Item-scoped: Are you over 10?
|
||||
- If over quota: Delete unused dimensions
|
||||
|
||||
5. **Check minimum traffic threshold**
|
||||
- Dimension needs at least 1000 events with parameter
|
||||
- Low-traffic dimensions may not populate
|
||||
- Wait longer if very low traffic
|
||||
|
||||
### Parameter Appears in DebugView But Not Reports
|
||||
|
||||
- **Expected in first 24 hours** - Normal, wait until 48
|
||||
- **After 48 hours** - Troubleshoot above
|
||||
|
||||
### Multiple Duplicates Created By Mistake
|
||||
|
||||
- Delete all but one copy
|
||||
- Wait 24-48 hours between deletions
|
||||
- Recreate if needed
|
||||
|
||||
### Can't Find Parameter in DebugView
|
||||
|
||||
- **Code may not be live** - Verify changes deployed
|
||||
- **Parameter not sent** - Check event fires on intended action
|
||||
- **Event not triggering** - Test event manually
|
||||
- **DebugView device wrong** - Select correct device from dropdown
|
||||
|
||||
@@ -0,0 +1,579 @@
|
||||
# Custom Dimension Troubleshooting Guide
|
||||
|
||||
## Quick Diagnosis Flowchart
|
||||
|
||||
```
|
||||
Are custom dimensions appearing in reports?
|
||||
│
|
||||
├─ YES → Is data accurate?
|
||||
│ ├─ YES → No action needed
|
||||
│ └─ NO → Jump to "Inaccurate Data" section
|
||||
│
|
||||
└─ NO → Is it after 48 hours?
|
||||
├─ NO → Wait, normal processing delay (24-48 hours)
|
||||
└─ YES → Start troubleshooting below
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Most Common Issues & Solutions
|
||||
|
||||
### Issue 1: Dimension Doesn't Appear After 48 Hours
|
||||
|
||||
**Frequency:** 95% of reported problems
|
||||
|
||||
#### Check 1: Verify Code Still Sends Parameter
|
||||
|
||||
Go to DebugView to see if current events include the parameter:
|
||||
|
||||
1. GA4 Admin → DebugView
|
||||
2. Look at events fired in last 5 minutes
|
||||
3. Find the event type (form_submit, page_view, etc.)
|
||||
4. Click to expand event details
|
||||
5. Look for parameter in list
|
||||
|
||||
**Expected:** Parameter appears with correct value
|
||||
|
||||
**If Parameter Missing:**
|
||||
- Code may not be live (deployment issue)
|
||||
- Event may not be triggering at expected action
|
||||
- Parameter may have been removed from code
|
||||
- Test the action manually to verify event fires
|
||||
|
||||
**Solution:**
|
||||
```javascript
|
||||
// Verify code actively sending parameter
|
||||
gtag('event', 'test_event', {
|
||||
'test_param': 'test_value'
|
||||
});
|
||||
// Check DebugView for this event
|
||||
```
|
||||
|
||||
#### Check 2: Verify Case-Sensitive Parameter Name Match
|
||||
|
||||
GA4 is **case-sensitive**. The parameter name in code must match EXACTLY in registration.
|
||||
|
||||
**DebugView shows:** `form_name`
|
||||
**Registered as:** `form_name` ✓ CORRECT
|
||||
**Registered as:** `Form_Name` ✗ WRONG
|
||||
**Registered as:** `formName` ✗ WRONG
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. Go to DebugView
|
||||
2. Find event with parameter
|
||||
3. Look at EXACT parameter name as shown
|
||||
4. Copy that exact name
|
||||
5. Compare to what you registered
|
||||
|
||||
**If mismatch found:**
|
||||
- Delete incorrect dimension
|
||||
- Create new dimension with correct parameter name
|
||||
- Wait 24-48 hours
|
||||
|
||||
#### Check 3: Verify Scope is Correct
|
||||
|
||||
Wrong scope will cause dimension to not appear properly.
|
||||
|
||||
**For event-scoped parameters:**
|
||||
- Parameter appears in gtag('event') call
|
||||
- Each event can have different value
|
||||
- Example: button_name varies by event
|
||||
|
||||
```javascript
|
||||
// If code looks like this → use EVENT scope
|
||||
gtag('event', 'click', {
|
||||
'button_name': 'Subscribe' // Different per event
|
||||
});
|
||||
```
|
||||
|
||||
**For user-scoped parameters:**
|
||||
- Parameter appears in gtag('set') call
|
||||
- Set once, applies to all events
|
||||
- Example: subscription_tier remains same
|
||||
|
||||
```javascript
|
||||
// If code looks like this → use USER scope
|
||||
gtag('set', {
|
||||
'subscription_tier': 'premium' // Same for all events
|
||||
});
|
||||
```
|
||||
|
||||
**For item-scoped parameters:**
|
||||
- Parameter in items array
|
||||
- Goes inside each product object
|
||||
- Example: item_color varies per product
|
||||
|
||||
```javascript
|
||||
// If code looks like this → use ITEM scope
|
||||
gtag('event', 'purchase', {
|
||||
'items': [{
|
||||
'item_color': 'blue' // Different per item
|
||||
}]
|
||||
});
|
||||
```
|
||||
|
||||
**Solution:**
|
||||
- If scope wrong: Delete and recreate with correct scope
|
||||
- Scope cannot be changed on existing dimension
|
||||
|
||||
#### Check 4: Verify Quota Not Exceeded
|
||||
|
||||
Standard GA4 property limits:
|
||||
- Event-scoped dimensions: 50 maximum
|
||||
- User-scoped dimensions: 25 maximum
|
||||
- Item-scoped dimensions: 10 maximum
|
||||
|
||||
If at or over limit, GA4 silently fails to create dimension.
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. Admin → Custom Definitions
|
||||
2. Count existing dimensions by scope
|
||||
3. If at limit: Delete unused dimensions
|
||||
4. Then recreate the missing dimension
|
||||
|
||||
**Example deletion process:**
|
||||
|
||||
1. Find unused dimension in list
|
||||
2. Click to select it
|
||||
3. Click **Delete**
|
||||
4. Confirm deletion
|
||||
5. Wait 24 hours before creating replacement
|
||||
|
||||
#### Check 5: Verify Minimum Event Volume
|
||||
|
||||
Custom dimensions need sufficient event volume to populate in reports.
|
||||
|
||||
**Minimum for visibility:**
|
||||
- At least 1,000 events with that parameter
|
||||
- May not show if traffic very low
|
||||
|
||||
**Solution:**
|
||||
- Check event volume in DebugView
|
||||
- If traffic low, data will eventually populate
|
||||
- Large websites: Usually visible within 48 hours
|
||||
- Small websites: May take longer or be below threshold
|
||||
|
||||
**For testing with low traffic:**
|
||||
- Use Realtime reports (shows faster)
|
||||
- Check after several days of data collection
|
||||
- Consider sampling: Manual filter to subset of users
|
||||
|
||||
#### Check 6: Verify Data Stream is Correct
|
||||
|
||||
Custom dimensions apply to their data stream. If created for wrong stream:
|
||||
|
||||
**Problem:** Created dimension for Data Stream A, but code sends to Data Stream B
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. Verify Measurement ID in code
|
||||
```javascript
|
||||
gtag('config', 'G-XXXXXXXXXX'); // This is the data stream
|
||||
```
|
||||
|
||||
2. Admin → Data Streams
|
||||
3. Match Measurement ID to correct stream
|
||||
4. Verify dimension created in THAT stream (not another)
|
||||
5. If in wrong stream: Create in correct stream
|
||||
|
||||
---
|
||||
|
||||
### Issue 2: Parameter in DebugView But Not in Reports
|
||||
|
||||
**Timeline:**
|
||||
- Hour 0-6: Parameter fires in DebugView
|
||||
- Hour 6-24: Should start appearing in reports
|
||||
- Hour 24-48: Definitely should appear in reports
|
||||
|
||||
#### Within First 24 Hours: Normal
|
||||
|
||||
GA4 requires time to process events. This is expected behavior.
|
||||
|
||||
**Solution:** Wait until 48-hour mark, then check again.
|
||||
|
||||
#### After 48 Hours: Investigate
|
||||
|
||||
Use the diagnostic checklist above (Checks 1-6) to identify issue.
|
||||
|
||||
---
|
||||
|
||||
### Issue 3: Dimension Values Inconsistent or Wrong
|
||||
|
||||
#### Problem: All Users Show Same Value
|
||||
|
||||
**For event-scoped dimension:**
|
||||
- ✗ WRONG: All events showing "Button A" when multiple buttons exist
|
||||
- Cause: Parameter only sent sometimes
|
||||
- Solution: Verify code sends parameter for ALL instances
|
||||
|
||||
**For user-scoped dimension:**
|
||||
- ✓ EXPECTED: All events from user showing "Premium" tier
|
||||
- This is correct behavior for user scope
|
||||
|
||||
#### Problem: Null or Empty Values Appearing
|
||||
|
||||
**Cause:** Parameter sometimes not sent
|
||||
|
||||
Example:
|
||||
```javascript
|
||||
gtag('event', 'form_submit', {
|
||||
'form_name': formElement.getAttribute('name') // Could be null
|
||||
});
|
||||
```
|
||||
|
||||
If `formElement` doesn't exist or attribute missing → null value sent
|
||||
|
||||
**Solution:**
|
||||
```javascript
|
||||
gtag('event', 'form_submit', {
|
||||
'form_name': formElement.getAttribute('name') || 'unknown_form'
|
||||
});
|
||||
```
|
||||
|
||||
Always provide default value.
|
||||
|
||||
#### Problem: Unexpected Values in Reports
|
||||
|
||||
Example: Report shows "button name: [object Object]" instead of actual name
|
||||
|
||||
**Cause:** Sending object or array instead of string
|
||||
|
||||
```javascript
|
||||
// WRONG - sending object
|
||||
gtag('event', 'click', {
|
||||
'button_data': {name: 'Subscribe'} // Object, not string!
|
||||
});
|
||||
|
||||
// CORRECT - send string value
|
||||
gtag('event', 'click', {
|
||||
'button_name': 'Subscribe' // String value
|
||||
});
|
||||
```
|
||||
|
||||
**Solution:** Ensure values are primitive types (string, number, boolean)
|
||||
|
||||
---
|
||||
|
||||
### Issue 4: Multiple Dimensions Created by Accident
|
||||
|
||||
**Problem:** Accidentally created "form_name", "form_Name", "formName" (all slightly different)
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. Delete the incorrect/duplicate versions
|
||||
2. Keep only the correct one
|
||||
3. Wait 24-48 hours between deletions
|
||||
4. Verify code sends correct parameter name
|
||||
|
||||
**Deletion process:**
|
||||
1. Admin → Custom Definitions
|
||||
2. Click each duplicate
|
||||
3. Click **Delete**
|
||||
4. Confirm
|
||||
5. Wait 24 hours
|
||||
6. Verify deletion complete
|
||||
|
||||
---
|
||||
|
||||
### Issue 5: Dimension Quota Exceeded
|
||||
|
||||
**Error:** Cannot create new dimension, hitting quota limit
|
||||
|
||||
**Standard GA4 Quotas:**
|
||||
- Event-scoped: 50 max (currently using X)
|
||||
- User-scoped: 25 max (currently using X)
|
||||
- Item-scoped: 10 max (currently using X)
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. Admin → Custom Definitions
|
||||
2. Identify unused dimensions
|
||||
3. Delete low-priority dimensions
|
||||
4. Now create new dimension
|
||||
|
||||
**Prioritization for deletion:**
|
||||
- Delete: Dimensions with no data
|
||||
- Delete: Dimensions not used in reports
|
||||
- Delete: Experimental/testing dimensions
|
||||
- Keep: Critical business metrics
|
||||
- Keep: Frequently used dimensions
|
||||
|
||||
---
|
||||
|
||||
## Dimension Data Quality Issues
|
||||
|
||||
### Issue 6: High-Cardinality Dimensions (Too Many Values)
|
||||
|
||||
**What is cardinality?**
|
||||
- Low: Few unique values (colors: red, blue, green)
|
||||
- High: Many unique values (email addresses, IDs)
|
||||
|
||||
**Problem:** Creating dimension on high-cardinality parameter
|
||||
|
||||
Example:
|
||||
```javascript
|
||||
gtag('event', 'form_submit', {
|
||||
'user_email': user.email // MILLIONS of unique values
|
||||
});
|
||||
```
|
||||
|
||||
**Impact:**
|
||||
- Report becomes unwieldy
|
||||
- Performance impacts
|
||||
- GA4 may limit display (shows "other" for rare values)
|
||||
|
||||
**Solution:** Use low-cardinality parameters
|
||||
|
||||
**Good parameters (low cardinality):**
|
||||
- Button names: 5-10 values
|
||||
- Form names: 3-8 values
|
||||
- User tiers: 3-5 values
|
||||
- Colors: 6-10 values
|
||||
- Locations: 20-100 values
|
||||
|
||||
**Bad parameters (high cardinality):**
|
||||
- Email addresses: Millions
|
||||
- User IDs: Millions
|
||||
- Timestamps: Continuous
|
||||
- Session IDs: Unique per session
|
||||
- Product SKUs: Often thousands+
|
||||
|
||||
**Fix:**
|
||||
- Don't track high-cardinality data as custom dimension
|
||||
- Use for analysis in DebugView only
|
||||
- Or aggregate: Convert `product_sku` to `product_category`
|
||||
|
||||
### Issue 7: Sending PII (Personally Identifiable Information)
|
||||
|
||||
**Prohibited:** Email, phone, SSN, credit card, name, IP address
|
||||
|
||||
```javascript
|
||||
// WRONG - Don't send PII
|
||||
gtag('event', 'signup', {
|
||||
'user_email': 'john@example.com', // PII!
|
||||
'user_name': 'John Doe' // PII!
|
||||
});
|
||||
```
|
||||
|
||||
**Solution:** Use anonymous identifiers
|
||||
|
||||
```javascript
|
||||
// CORRECT - Use hashed or anonymous IDs
|
||||
gtag('event', 'signup', {
|
||||
'user_tier': 'free', // OK - non-PII attribute
|
||||
'signup_source': 'newsletter' // OK - non-PII context
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Debugging with DebugView
|
||||
|
||||
### Enable DebugView (Three Methods)
|
||||
|
||||
#### Method 1: Chrome Extension (Easiest)
|
||||
|
||||
1. Install "Google Analytics Debugger" from Chrome Web Store
|
||||
2. Click extension icon → Enable
|
||||
3. Refresh website
|
||||
4. Go to GA4 Admin → DebugView
|
||||
5. Data appears immediately
|
||||
|
||||
#### Method 2: GTM Preview Mode
|
||||
|
||||
1. In GTM container → Click Preview
|
||||
2. All GA4 tags automatically send debug_mode parameter
|
||||
3. Go to GA4 DebugView
|
||||
4. Data visible
|
||||
|
||||
#### Method 3: Manual Debug Code
|
||||
|
||||
```javascript
|
||||
gtag('config', 'G-XXXXXXXXXX', {
|
||||
'debug_mode': true
|
||||
});
|
||||
|
||||
// Or per event
|
||||
gtag('event', 'form_submit', {
|
||||
'form_name': 'Contact',
|
||||
'debug_mode': true
|
||||
});
|
||||
```
|
||||
|
||||
### Using DebugView to Diagnose
|
||||
|
||||
**Verification Checklist:**
|
||||
|
||||
1. ✓ Event fires? See it in event stream
|
||||
2. ✓ Parameter sends? See in event parameters
|
||||
3. ✓ Parameter name correct? Check exact spelling/case
|
||||
4. ✓ Parameter value correct? See actual value sent
|
||||
5. ✓ Scope correct? User params in "User properties", item params in "Items"
|
||||
|
||||
**DebugView Navigation:**
|
||||
|
||||
- **Left panel:** Event stream (click to select)
|
||||
- **Right panel:** Event details (expand sections)
|
||||
- **User properties section:** Find user-scoped dimensions
|
||||
- **Items section:** Find item-scoped dimensions
|
||||
|
||||
---
|
||||
|
||||
## Testing Custom Dimensions
|
||||
|
||||
### Manual Testing Workflow
|
||||
|
||||
1. **Create test dimension**
|
||||
- Name: "Test Dimension [your name]"
|
||||
- Register the test parameter
|
||||
|
||||
2. **Add test code to page**
|
||||
```javascript
|
||||
gtag('event', 'test_event', {
|
||||
'test_parameter': 'test_value_' + new Date().toLocaleTimeString()
|
||||
});
|
||||
```
|
||||
|
||||
3. **Verify in DebugView**
|
||||
- Trigger event manually
|
||||
- See parameter in DebugView
|
||||
- Confirm parameter name matches registration
|
||||
|
||||
4. **Wait 24-48 hours**
|
||||
|
||||
5. **Check test report**
|
||||
- Analytics → Reports
|
||||
- Add test dimension
|
||||
- See test values appear
|
||||
|
||||
6. **Delete test dimension**
|
||||
- Once verified
|
||||
- Clean up test data
|
||||
|
||||
---
|
||||
|
||||
## Getting Help & Debugging Checklist
|
||||
|
||||
### Before Contacting Support
|
||||
|
||||
Use this checklist to diagnose issue:
|
||||
|
||||
- [ ] Parameter appears in DebugView?
|
||||
- YES: Parameter is being sent correctly
|
||||
- NO: Issue is in implementation, not GA4
|
||||
|
||||
- [ ] Parameter name matches registration (case-sensitive)?
|
||||
- YES: Continue
|
||||
- NO: Fix parameter name
|
||||
|
||||
- [ ] Scope selection correct (Event/User/Item)?
|
||||
- YES: Continue
|
||||
- NO: Delete and recreate with correct scope
|
||||
|
||||
- [ ] Under quota for scope type?
|
||||
- YES: Continue
|
||||
- NO: Delete unused dimensions
|
||||
|
||||
- [ ] 48 hours passed since registration?
|
||||
- YES: Continue
|
||||
- NO: Wait longer, processing is normal
|
||||
|
||||
- [ ] Sufficient event volume (1000+ events)?
|
||||
- YES: Continue
|
||||
- NO: May appear later as traffic increases
|
||||
|
||||
### Debug Information to Gather
|
||||
|
||||
If contacting support, provide:
|
||||
|
||||
1. **GA4 Property ID:** properties/XXXXXXXXXX
|
||||
2. **Dimension name:** Exactly as registered
|
||||
3. **Parameter name:** Exactly as sent
|
||||
4. **Scope:** Event/User/Item
|
||||
5. **Date created:** When dimension registered
|
||||
6. **Event type:** Which event sends parameter
|
||||
7. **DebugView screenshot:** Showing parameter
|
||||
8. **Expected vs actual:** What should appear vs what does
|
||||
|
||||
---
|
||||
|
||||
## Prevention: Best Practices
|
||||
|
||||
### Avoid Problems Before They Start
|
||||
|
||||
1. **Plan before implementation**
|
||||
- List all dimensions needed
|
||||
- Assign scopes to each
|
||||
- Check quota (don't exceed limits)
|
||||
- Get team approval
|
||||
|
||||
2. **Use consistent naming**
|
||||
- Standardize parameter names
|
||||
- Use snake_case
|
||||
- Clear, descriptive names
|
||||
- Document all parameters
|
||||
|
||||
3. **Test with small rollout**
|
||||
- Deploy to 1% of traffic first
|
||||
- Verify in DebugView
|
||||
- Wait 24-48 hours
|
||||
- Then full rollout
|
||||
|
||||
4. **Version control parameters**
|
||||
- If updating parameter name: Create new dimension
|
||||
- Don't modify existing dimensions
|
||||
- Keep version history
|
||||
|
||||
5. **Monitor after creation**
|
||||
- Check data appears after 48 hours
|
||||
- Verify data accuracy
|
||||
- Monitor for unexpected values
|
||||
- Set up alerts for anomalies
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference: Common Error Messages
|
||||
|
||||
| Error | Cause | Solution |
|
||||
|-------|-------|----------|
|
||||
| "Dimension not found" | Registered with wrong name | Create with correct name |
|
||||
| "Parameter mismatch" | Case doesn't match | Verify exact case in DebugView |
|
||||
| "Cannot create dimension" | Quota exceeded | Delete unused dimensions |
|
||||
| "Dimension appears empty" | No data sent | Verify code sends parameter |
|
||||
| "Shows '[object Object]'" | Sending object not string | Send string value only |
|
||||
| "All values blank/null" | Parameter optional, sometimes missing | Add default value in code |
|
||||
|
||||
---
|
||||
|
||||
## Advanced: Debugging with GA4 DebugView API
|
||||
|
||||
For developers, use the Realtime Report API to programmatically verify:
|
||||
|
||||
```python
|
||||
from google.analytics.data_v1beta import BetaAnalyticsDataClient
|
||||
|
||||
client = BetaAnalyticsDataClient()
|
||||
|
||||
# Run realtime report to verify custom dimension
|
||||
response = client.run_realtime_report(
|
||||
request={
|
||||
"property": "properties/PROPERTY_ID",
|
||||
"dimensions": [
|
||||
{"name": "customEvent:dimension_name"}
|
||||
],
|
||||
"metrics": [
|
||||
{"name": "eventCount"}
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
# Check if dimension appears with data
|
||||
for row in response.rows:
|
||||
print(f"Dimension value: {row.dimension_values}")
|
||||
print(f"Event count: {row.metric_values}")
|
||||
```
|
||||
|
||||
This confirms dimension is receiving data in real-time.
|
||||
|
||||
538
skills/ga4-custom-dimensions/references/scopes-complete-guide.md
Normal file
538
skills/ga4-custom-dimensions/references/scopes-complete-guide.md
Normal file
@@ -0,0 +1,538 @@
|
||||
# Complete Guide to GA4 Dimension Scopes
|
||||
|
||||
## Scope Fundamentals
|
||||
|
||||
A **scope** in GA4 determines the range of applicability for a custom dimension:
|
||||
- What it applies to (event, user, or product)
|
||||
- How long it persists
|
||||
- When and where it appears in reports
|
||||
|
||||
Understanding scope is critical because the same parameter name with different scopes creates completely different tracking behavior.
|
||||
|
||||
## Event Scope Deep Dive
|
||||
|
||||
### Definition
|
||||
|
||||
Event-scoped dimensions apply to a single event occurrence only. Once that event is recorded, the dimension value is tied exclusively to that event.
|
||||
|
||||
### Characteristics
|
||||
|
||||
- **Scope**: Single event only
|
||||
- **Lifespan**: Duration of that one event
|
||||
- **Persistence**: No carryover to other events
|
||||
- **Reporting**: Appears only for that event type
|
||||
- **Reusability**: Same dimension name can have different values across events
|
||||
- **Quota**: 50 per standard GA4 property
|
||||
|
||||
### Implementation
|
||||
|
||||
**Basic event with event-scoped parameter:**
|
||||
|
||||
```javascript
|
||||
gtag('event', 'form_submit', {
|
||||
'form_name': 'Contact Form', // Event-scoped
|
||||
'form_id': 'contact-form-v2', // Event-scoped
|
||||
'form_destination': '/thank-you', // Event-scoped
|
||||
'form_field_count': 8 // Event-scoped
|
||||
});
|
||||
```
|
||||
|
||||
**Each event sends these parameters independently:**
|
||||
|
||||
```javascript
|
||||
// First form submission
|
||||
gtag('event', 'form_submit', {
|
||||
'form_name': 'Contact Form'
|
||||
});
|
||||
|
||||
// Later, different form submission
|
||||
gtag('event', 'form_submit', {
|
||||
'form_name': 'Newsletter Signup' // Different value, same event
|
||||
});
|
||||
```
|
||||
|
||||
### Use Cases
|
||||
|
||||
| Use Case | Parameter | Example |
|
||||
|----------|-----------|---------|
|
||||
| Which form? | form_name | "Contact", "Newsletter", "Demo Request" |
|
||||
| Which video? | video_title | "GA4 Basics", "Advanced Analytics" |
|
||||
| Which button? | button_name | "Subscribe", "Download", "Add to Cart" |
|
||||
| Which search term? | search_query | "analytics", "reporting" |
|
||||
| Which page? | page_section | "header", "sidebar", "footer" |
|
||||
| Which error? | error_message | "404", "500", "timeout" |
|
||||
|
||||
### Admin Registration Example
|
||||
|
||||
**Creating "Form Name" Event-Scoped Dimension:**
|
||||
|
||||
1. Admin → Data Display → Custom Definitions
|
||||
2. Click "Create Custom Dimension"
|
||||
3. Dimension Name: "Form Name"
|
||||
4. Scope: **Event** (select this)
|
||||
5. Event Parameter: "form_name" (exact match from code)
|
||||
6. Description: "Name of form submitted (contact, newsletter, etc)"
|
||||
7. Save
|
||||
|
||||
**Result:** In reports, filter/analyze by "Form Name" dimension showing all form submissions
|
||||
|
||||
### Common Mistakes
|
||||
|
||||
**Mistake 1:** Using event-scoped dimension for persistent user data
|
||||
|
||||
```javascript
|
||||
// WRONG: Event scope for user property
|
||||
gtag('event', 'page_view', {
|
||||
'subscription_tier': 'premium' // Should be user scope!
|
||||
});
|
||||
```
|
||||
|
||||
**Correct:** Use user scope for persistent attributes
|
||||
|
||||
```javascript
|
||||
gtag('set', {
|
||||
'subscription_tier': 'premium' // User scope - persists
|
||||
});
|
||||
```
|
||||
|
||||
**Mistake 2:** Sending same event-scoped dimension with every event
|
||||
|
||||
```javascript
|
||||
// INEFFICIENT: Redundant in every event
|
||||
gtag('event', 'page_view', {
|
||||
'user_location': 'New York' // Repeating same value
|
||||
});
|
||||
gtag('event', 'button_click', {
|
||||
'user_location': 'New York' // Same value repeated
|
||||
});
|
||||
```
|
||||
|
||||
**Better:** Use user scope instead
|
||||
|
||||
```javascript
|
||||
gtag('set', {
|
||||
'user_location': 'New York' // Set once, applies to all
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## User Scope Deep Dive
|
||||
|
||||
### Definition
|
||||
|
||||
User-scoped dimensions (user properties) apply to all events from a user within a session. Set once, they persist across multiple events.
|
||||
|
||||
### Characteristics
|
||||
|
||||
- **Scope**: All events from that user
|
||||
- **Lifespan**: User session (or until explicitly cleared)
|
||||
- **Persistence**: Applies retroactively to events within session
|
||||
- **Reporting**: Appears across all event types for that user
|
||||
- **Reusability**: Can be used in audiences, segments, and filters
|
||||
- **Quota**: 25 per standard GA4 property
|
||||
- **Best for**: User attributes and customer characteristics
|
||||
|
||||
### Implementation
|
||||
|
||||
**Setting user properties once, applying to all events:**
|
||||
|
||||
```javascript
|
||||
// User logs in - set properties once
|
||||
gtag('set', {
|
||||
'subscription_tier': 'premium',
|
||||
'customer_id': 'CUST_12345',
|
||||
'years_customer': 5,
|
||||
'account_status': 'active',
|
||||
'preferred_language': 'en'
|
||||
});
|
||||
|
||||
// All subsequent events automatically include these user properties
|
||||
gtag('event', 'page_view'); // Includes user properties
|
||||
gtag('event', 'button_click', {...}); // Includes user properties
|
||||
gtag('event', 'purchase', {...}); // Includes user properties
|
||||
```
|
||||
|
||||
### Predefined User Properties
|
||||
|
||||
GA4 automatically collects certain user properties without additional code:
|
||||
|
||||
```
|
||||
language Browser/app language
|
||||
first_open_date First app launch date
|
||||
first_visit_date First website visit date
|
||||
ga_session_id Current session ID
|
||||
ga_session_number Session count for user
|
||||
```
|
||||
|
||||
### Use Cases
|
||||
|
||||
| Use Case | Property | Example Values |
|
||||
|----------|----------|-----------------|
|
||||
| Subscription level | subscription_tier | free, pro, enterprise |
|
||||
| Customer segment | customer_segment | new, returning, vip |
|
||||
| Account status | account_status | active, inactive, trial |
|
||||
| Industry | industry | technology, finance, retail |
|
||||
| Company size | company_size | small, medium, enterprise |
|
||||
| Loyalty level | loyalty_status | bronze, silver, gold, platinum |
|
||||
| Location | location | New York, London, Tokyo |
|
||||
| Preferred language | preferred_language | en, es, fr, de |
|
||||
| Revenue bracket | annual_revenue | 0-100k, 100k-1m, 1m+ |
|
||||
| Tenure | years_customer | 1, 5, 10+ |
|
||||
|
||||
### Admin Registration Example
|
||||
|
||||
**Creating "Customer Segment" User-Scoped Dimension:**
|
||||
|
||||
1. Admin → Data Display → Custom Definitions
|
||||
2. Click "Create Custom Dimension"
|
||||
3. Dimension Name: "Customer Segment"
|
||||
4. Scope: **User** (select this)
|
||||
5. User Property: "customer_segment"
|
||||
6. Description: "Customer type: new, returning, vip"
|
||||
7. Save
|
||||
|
||||
**Result:** All events from that user labeled with their customer segment
|
||||
|
||||
### Clearing User Properties
|
||||
|
||||
User properties persist until explicitly cleared:
|
||||
|
||||
```javascript
|
||||
// Clear single user property
|
||||
gtag('set', {
|
||||
'subscription_tier': null // Set to null to clear
|
||||
});
|
||||
|
||||
// Clear on user logout
|
||||
gtag('set', {
|
||||
'subscription_tier': null,
|
||||
'customer_id': null,
|
||||
'account_status': null
|
||||
});
|
||||
```
|
||||
|
||||
**Critical:** Always set to `null`, not empty string `""`. Empty string persists as a value.
|
||||
|
||||
### User Properties vs User ID
|
||||
|
||||
**User ID** (different from user properties):
|
||||
- Enables cross-device and cross-session tracking
|
||||
- Single identifier per user
|
||||
- Set with `gtag('set', {'user_id': 'value'})`
|
||||
|
||||
**User Properties:**
|
||||
- Multiple attributes about user
|
||||
- Applied to all events from user
|
||||
- Set with `gtag('set', {property: value})`
|
||||
|
||||
---
|
||||
|
||||
## Item Scope Deep Dive
|
||||
|
||||
### Definition
|
||||
|
||||
Item-scoped dimensions apply to individual products within ecommerce events (purchase, add_to_cart, view_item, etc.). Each product in the items array can have its own item-scoped dimension values.
|
||||
|
||||
### Characteristics
|
||||
|
||||
- **Scope**: Individual items in items array
|
||||
- **Lifespan**: That transaction/event only
|
||||
- **Persistence**: No carryover to future transactions
|
||||
- **Reporting**: Product-level analysis in ecommerce reports
|
||||
- **Quota**: 10 per standard GA4 property
|
||||
- **Applies To**: purchase, add_to_cart, remove_from_cart, view_item, etc.
|
||||
- **Array Structure**: Sits within items array objects
|
||||
|
||||
### Implementation
|
||||
|
||||
**Item-scoped parameters in items array:**
|
||||
|
||||
```javascript
|
||||
gtag('event', 'purchase', {
|
||||
'items': [
|
||||
{
|
||||
'item_id': 'SKU_123',
|
||||
'item_name': 'Blue T-Shirt',
|
||||
'price': 29.99,
|
||||
'quantity': 2,
|
||||
// ITEM-SCOPED CUSTOM DIMENSIONS:
|
||||
'item_color': 'blue', // Which color?
|
||||
'item_size': 'large', // Which size?
|
||||
'supplier': 'Vendor A', // Which supplier?
|
||||
'warehouse_location': 'NY' // Which warehouse?
|
||||
},
|
||||
{
|
||||
'item_id': 'SKU_124',
|
||||
'item_name': 'Gray Pants',
|
||||
'price': 49.99,
|
||||
'quantity': 1,
|
||||
// DIFFERENT VALUES for second item:
|
||||
'item_color': 'gray', // Different color
|
||||
'item_size': 'medium', // Different size
|
||||
'supplier': 'Vendor B', // Different supplier
|
||||
'warehouse_location': 'LA' // Different warehouse
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
### Use Cases
|
||||
|
||||
| Use Case | Parameter | Example Values |
|
||||
|----------|-----------|-----------------|
|
||||
| Product color | item_color | red, blue, green, black |
|
||||
| Product size | item_size | small, medium, large, xl |
|
||||
| Supplier/vendor | supplier | "Vendor A", "Vendor B", "Internal" |
|
||||
| Product quality tier | item_quality | standard, premium, luxury |
|
||||
| Warehouse | warehouse_location | NY, LA, London, Tokyo |
|
||||
| Product condition | condition | new, refurbished, used |
|
||||
| Fabric type | fabric_type | cotton, polyester, silk |
|
||||
| Season | season | spring, summer, fall, winter |
|
||||
| Sustainability | eco_friendly | true, false |
|
||||
| Gender/age | target_demographic | mens, womens, kids |
|
||||
|
||||
### Admin Registration Example
|
||||
|
||||
**Creating "Item Color" Item-Scoped Dimension:**
|
||||
|
||||
1. Admin → Data Display → Custom Definitions
|
||||
2. Click "Create Custom Dimension"
|
||||
3. Dimension Name: "Item Color"
|
||||
4. Scope: **Item** (select this)
|
||||
5. Event Parameter: "item_color"
|
||||
6. Description: "Color variant of product"
|
||||
7. Save
|
||||
|
||||
**Result:** Ecommerce reports can analyze "Which colors sell best?" by revenue, quantity, etc.
|
||||
|
||||
### Accessing Item-Scoped Data in Reports
|
||||
|
||||
Standard GA4 reports:
|
||||
1. Analytics → Reports → Monetization → Items
|
||||
2. See products with custom dimensions
|
||||
3. Add "Item Color" dimension to table
|
||||
4. Sort/filter by color
|
||||
|
||||
Explorations:
|
||||
1. Analytics → Explore
|
||||
2. Use Item-related dimensions and metrics
|
||||
3. Create "Items by Color" report
|
||||
4. Analyze revenue, quantity, performance by item dimension
|
||||
|
||||
### Complete Purchase Example
|
||||
|
||||
```javascript
|
||||
// Complete purchase with all item types and item-scoped dimensions
|
||||
gtag('event', 'purchase', {
|
||||
'transaction_id': 'TXN_' + Date.now(),
|
||||
'value': 189.97,
|
||||
'currency': 'USD',
|
||||
'items': [
|
||||
{
|
||||
// Standard fields (required)
|
||||
'item_id': 'SKU_SHIRT_BLUE_L',
|
||||
'item_name': 'Blue T-Shirt',
|
||||
'price': 29.99,
|
||||
'quantity': 2,
|
||||
|
||||
// Google-recommended fields (highly recommended)
|
||||
'item_category': 'Apparel',
|
||||
'item_brand': 'My Brand',
|
||||
'item_variant': 'Blue/Large',
|
||||
|
||||
// CUSTOM ITEM-SCOPED DIMENSIONS:
|
||||
'item_color': 'blue',
|
||||
'item_size': 'large',
|
||||
'supplier': 'Vendor A',
|
||||
'warehouse_location': 'New York'
|
||||
},
|
||||
{
|
||||
'item_id': 'SKU_PANTS_GRAY_M',
|
||||
'item_name': 'Gray Pants',
|
||||
'price': 49.99,
|
||||
'quantity': 2,
|
||||
'item_category': 'Apparel',
|
||||
'item_brand': 'My Brand',
|
||||
'item_variant': 'Gray/Medium',
|
||||
|
||||
// CUSTOM ITEM-SCOPED DIMENSIONS (different values):
|
||||
'item_color': 'gray',
|
||||
'item_size': 'medium',
|
||||
'supplier': 'Vendor B',
|
||||
'warehouse_location': 'Los Angeles'
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Scope Decision Framework
|
||||
|
||||
Use this framework to select correct scope:
|
||||
|
||||
### Decision Tree
|
||||
|
||||
**Is this data...**
|
||||
|
||||
1. **About a single event occurrence?**
|
||||
- YES → Use **Event scope**
|
||||
- Example: "Which button was clicked?" → button_name (event-scoped)
|
||||
|
||||
2. **About the user, applying to all their events?**
|
||||
- YES → Use **User scope**
|
||||
- Example: "What's user's subscription level?" → subscription_tier (user-scoped)
|
||||
|
||||
3. **About individual products in ecommerce events?**
|
||||
- YES → Use **Item scope**
|
||||
- Example: "Which color was purchased?" → item_color (item-scoped)
|
||||
|
||||
4. **About the same thing, but sometimes changes per event?**
|
||||
- YES → Use **Event scope** (not user scope)
|
||||
- Example: "user_location" might change per page_view event → event-scoped
|
||||
|
||||
### Scope Selection Matrix
|
||||
|
||||
| Question | Event | User | Item |
|
||||
|----------|-------|------|------|
|
||||
| Applies to single event only? | ✓ | ✗ | ✗ |
|
||||
| Applies to all user events? | ✗ | ✓ | ✗ |
|
||||
| Applies to products in purchase? | ✗ | ✗ | ✓ |
|
||||
| Persists across sessions? | ✗ | ✓ | ✗ |
|
||||
| Can have different values per event? | ✓ | ✗ | ✓ |
|
||||
| Used for audience building? | Limited | ✓ | Limited |
|
||||
| Used in conversion analysis? | ✓ | ✓ | ✓ |
|
||||
|
||||
## Scope Limits & Quotas
|
||||
|
||||
### Standard GA4 Property
|
||||
|
||||
- Event-scoped custom dimensions: 50 maximum
|
||||
- User-scoped custom dimensions: 25 maximum
|
||||
- Item-scoped custom dimensions: 10 maximum
|
||||
- Total custom metrics: 50 maximum
|
||||
- Total calculated metrics: 5 maximum
|
||||
|
||||
### GA4 360 Property
|
||||
|
||||
- Event-scoped custom dimensions: 125 maximum
|
||||
- User-scoped custom dimensions: 100 maximum
|
||||
- Item-scoped custom dimensions: 25 maximum
|
||||
- Total custom metrics: 125 maximum
|
||||
- Total calculated metrics: 50 maximum
|
||||
|
||||
### Choosing Which to Create
|
||||
|
||||
Prioritize by importance:
|
||||
|
||||
1. **Essential** - Required for business reporting (create first)
|
||||
2. **Important** - Nice to have, but useful (create second)
|
||||
3. **Nice-to-have** - Interesting but not critical (create if quota allows)
|
||||
|
||||
Example priority:
|
||||
|
||||
```
|
||||
High Priority (Event):
|
||||
- form_name (which forms submitted)
|
||||
- error_type (what errors users encounter)
|
||||
- page_section (where on page interactions happen)
|
||||
|
||||
High Priority (User):
|
||||
- subscription_tier (critical for segmentation)
|
||||
- customer_segment (key for analysis)
|
||||
|
||||
High Priority (Item):
|
||||
- item_color (what colors sell)
|
||||
- item_size (what sizes convert)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Scope Confusion Examples
|
||||
|
||||
### ❌ WRONG: Using Event Scope for User Data
|
||||
|
||||
```javascript
|
||||
// INCORRECT - This repeats the same value in every event
|
||||
gtag('event', 'page_view', {
|
||||
'subscription_tier': 'premium' // Event scope
|
||||
});
|
||||
|
||||
gtag('event', 'button_click', {
|
||||
'subscription_tier': 'premium' // Repeated!
|
||||
});
|
||||
|
||||
// Result: Bloated events, wasted parameters
|
||||
```
|
||||
|
||||
### ✅ CORRECT: Using User Scope for User Data
|
||||
|
||||
```javascript
|
||||
// CORRECT - Set once, applies to all events
|
||||
gtag('set', {
|
||||
'subscription_tier': 'premium' // User scope
|
||||
});
|
||||
|
||||
gtag('event', 'page_view'); // Automatically includes subscription_tier
|
||||
gtag('event', 'button_click', {}); // Automatically includes subscription_tier
|
||||
|
||||
// Result: Clean, efficient, applies everywhere
|
||||
```
|
||||
|
||||
### ❌ WRONG: Using User Scope for Event Data
|
||||
|
||||
```javascript
|
||||
// INCORRECT - "button_name" changes with every button click
|
||||
gtag('set', {
|
||||
'button_name': 'Download' // User scope - wrong!
|
||||
});
|
||||
|
||||
gtag('event', 'button_click'); // Later click on different button
|
||||
// Now it says all events came from "Download" button - wrong!
|
||||
```
|
||||
|
||||
### ✅ CORRECT: Using Event Scope for Event Data
|
||||
|
||||
```javascript
|
||||
// CORRECT - Each event captures its own button
|
||||
gtag('event', 'button_click', {
|
||||
'button_name': 'Download' // Event scope
|
||||
});
|
||||
|
||||
gtag('event', 'button_click', {
|
||||
'button_name': 'Subscribe' // Event scope - different value
|
||||
});
|
||||
|
||||
// Result: Accurate, event-specific tracking
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices by Scope
|
||||
|
||||
### Event Scope Best Practices
|
||||
|
||||
- Name descriptively (button_name, form_id, video_title)
|
||||
- Use for action-specific context
|
||||
- Avoid for user-level attributes
|
||||
- Can repeat across events with different values
|
||||
- Useful for "What happened?" analysis
|
||||
|
||||
### User Scope Best Practices
|
||||
|
||||
- Name as attributes (subscription_tier, customer_segment, account_status)
|
||||
- Use for persistent user characteristics
|
||||
- Set early in session (after authentication)
|
||||
- Clear on logout with `null`
|
||||
- Never use empty string to clear
|
||||
- Useful for "Who is this user?" analysis
|
||||
|
||||
### Item Scope Best Practices
|
||||
|
||||
- Use only in items array of ecommerce events
|
||||
- Name as item properties (item_color, item_size)
|
||||
- Keep values consistent across items
|
||||
- Register in Admin as Item scope
|
||||
- Useful for "What are we selling?" analysis
|
||||
|
||||
Reference in New Issue
Block a user