Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:32:40 +08:00
commit 0ea8352871
72 changed files with 30043 additions and 0 deletions

View 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

View File

@@ -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)

View 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 |

View File

@@ -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 |

View File

@@ -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

View File

@@ -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.

View 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