Initial commit
This commit is contained in:
@@ -0,0 +1,584 @@
|
||||
# Ecommerce Events Implementation Guide
|
||||
|
||||
## Complete Ecommerce Journey Tracking
|
||||
|
||||
This guide covers implementing the full customer journey from product discovery through purchase and refund handling.
|
||||
|
||||
---
|
||||
|
||||
## Ecommerce Event Flow
|
||||
|
||||
```
|
||||
1. view_item_list (User sees product listing)
|
||||
2. select_item / view_item (User views product details)
|
||||
3. add_to_cart (User adds product to cart)
|
||||
4. view_cart (User reviews cart)
|
||||
5. begin_checkout (User starts checkout - CRITICAL METRIC)
|
||||
6. add_shipping_info (User selects shipping)
|
||||
7. add_payment_info (User enters payment)
|
||||
8. purchase (Transaction complete - MAIN GOAL)
|
||||
9. refund (Optional: Product refunded)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step-by-Step Implementation
|
||||
|
||||
### Step 1: Product Listing Page
|
||||
|
||||
**Event:** `view_item_list`
|
||||
|
||||
**Purpose:** Track when user views product search results, category pages, or product collections
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
gtag('event', 'view_item_list', {
|
||||
'items': [
|
||||
{
|
||||
'item_id': 'SKU_001',
|
||||
'item_name': 'Blue T-Shirt',
|
||||
'item_category': 'Apparel',
|
||||
'price': 29.99
|
||||
},
|
||||
{
|
||||
'item_id': 'SKU_002',
|
||||
'item_name': 'Red T-Shirt',
|
||||
'item_category': 'Apparel',
|
||||
'price': 29.99
|
||||
}
|
||||
],
|
||||
'item_list_id': 'search_results',
|
||||
'item_list_name': 'Search Results for T-Shirts'
|
||||
});
|
||||
```
|
||||
|
||||
**Trigger Points:**
|
||||
- User lands on category page
|
||||
- Search results load
|
||||
- Related products section appears
|
||||
- Collection/sale page loads
|
||||
|
||||
**Reporting Use:**
|
||||
- "Items" report - view count by product
|
||||
- Funnel analysis - how many users view products
|
||||
- Product performance metrics
|
||||
|
||||
---
|
||||
|
||||
### Step 2: Product Detail Page
|
||||
|
||||
**Event:** `view_item`
|
||||
|
||||
**Purpose:** Track individual product views
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// Extract product data from page
|
||||
var productData = {
|
||||
id: document.getElementById('product-id').textContent,
|
||||
name: document.getElementById('product-name').textContent,
|
||||
price: parseFloat(document.getElementById('product-price').textContent),
|
||||
category: document.getElementById('product-category').textContent
|
||||
};
|
||||
|
||||
gtag('event', 'view_item', {
|
||||
'items': [{
|
||||
'item_id': productData.id,
|
||||
'item_name': productData.name,
|
||||
'item_category': productData.category,
|
||||
'item_brand': 'Your Brand',
|
||||
'item_variant': 'Blue/Large',
|
||||
'price': productData.price,
|
||||
'quantity': 1
|
||||
}],
|
||||
'value': productData.price,
|
||||
'currency': 'USD'
|
||||
});
|
||||
```
|
||||
|
||||
**Advanced Implementation (Multiple Variants):**
|
||||
```javascript
|
||||
gtag('event', 'view_item', {
|
||||
'items': [{
|
||||
'item_id': 'SKU_123',
|
||||
'item_name': 'Premium T-Shirt',
|
||||
'item_category': 'Apparel',
|
||||
'item_category2': 'Shirts',
|
||||
'item_category3': 'Premium',
|
||||
'item_brand': 'Brand Name',
|
||||
'item_variant': 'Blue',
|
||||
'item_list_name': 'Search Results',
|
||||
'price': 49.99,
|
||||
'quantity': 1
|
||||
}],
|
||||
'value': 49.99,
|
||||
'currency': 'USD'
|
||||
});
|
||||
```
|
||||
|
||||
**Trigger Points:**
|
||||
- Product detail page loads
|
||||
- User arrives via search or category link
|
||||
- Product page ready (after lazy-loading images)
|
||||
|
||||
---
|
||||
|
||||
### Step 3: Add to Cart
|
||||
|
||||
**Event:** `add_to_cart`
|
||||
|
||||
**Purpose:** Track when items are added to shopping cart
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
document.getElementById('add-to-cart-btn').addEventListener('click', function() {
|
||||
var quantity = parseInt(document.getElementById('quantity-input').value) || 1;
|
||||
var price = parseFloat(document.getElementById('product-price').textContent);
|
||||
var itemId = document.getElementById('product-id').textContent;
|
||||
|
||||
gtag('event', 'add_to_cart', {
|
||||
'items': [{
|
||||
'item_id': itemId,
|
||||
'item_name': 'Product Name',
|
||||
'item_category': 'Apparel',
|
||||
'price': price,
|
||||
'quantity': quantity
|
||||
}],
|
||||
'value': price * quantity,
|
||||
'currency': 'USD'
|
||||
});
|
||||
|
||||
// Proceed with cart addition
|
||||
addToCart(itemId, quantity);
|
||||
});
|
||||
```
|
||||
|
||||
**Important Notes:**
|
||||
- Value should be `price * quantity`
|
||||
- Send immediately when user clicks add button
|
||||
- Don't wait for backend confirmation
|
||||
- Always include items array
|
||||
|
||||
**Reporting Use:**
|
||||
- Add-to-cart rate metrics
|
||||
- Funnel drop-off analysis
|
||||
- Cart value trending
|
||||
|
||||
---
|
||||
|
||||
### Step 4: View Cart
|
||||
|
||||
**Event:** `view_cart`
|
||||
|
||||
**Purpose:** Track when user reviews shopping cart
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// On cart page load
|
||||
var cartItems = getCartItemsFromStorage(); // Your cart data
|
||||
var totalValue = 0;
|
||||
|
||||
var itemsArray = cartItems.map(function(item) {
|
||||
totalValue += item.price * item.quantity;
|
||||
return {
|
||||
'item_id': item.id,
|
||||
'item_name': item.name,
|
||||
'item_category': item.category,
|
||||
'price': item.price,
|
||||
'quantity': item.quantity
|
||||
};
|
||||
});
|
||||
|
||||
gtag('event', 'view_cart', {
|
||||
'items': itemsArray,
|
||||
'value': totalValue,
|
||||
'currency': 'USD'
|
||||
});
|
||||
```
|
||||
|
||||
**Trigger Points:**
|
||||
- User navigates to cart page
|
||||
- User views mini-cart
|
||||
- Cart updates after removing item
|
||||
|
||||
---
|
||||
|
||||
### Step 5: Begin Checkout (CRITICAL)
|
||||
|
||||
**Event:** `begin_checkout`
|
||||
|
||||
**Purpose:** Track when user initiates checkout (most important funnel metric)
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
document.getElementById('checkout-btn').addEventListener('click', function() {
|
||||
var cartItems = getCartItems();
|
||||
var totalValue = calculateCartTotal();
|
||||
|
||||
gtag('event', 'begin_checkout', {
|
||||
'items': cartItems.map(function(item) {
|
||||
return {
|
||||
'item_id': item.id,
|
||||
'item_name': item.name,
|
||||
'item_category': item.category,
|
||||
'price': item.price,
|
||||
'quantity': item.quantity
|
||||
};
|
||||
}),
|
||||
'value': totalValue,
|
||||
'currency': 'USD'
|
||||
});
|
||||
|
||||
// Navigate to checkout
|
||||
redirectToCheckout();
|
||||
});
|
||||
```
|
||||
|
||||
**Why It's Critical:**
|
||||
- Baseline funnel metric
|
||||
- Identifies cart abandonment
|
||||
- Used for conversion modeling
|
||||
- Compare begin_checkout to purchase ratio
|
||||
|
||||
**Trigger Points:**
|
||||
- User clicks "Checkout" button
|
||||
- User navigates to checkout page
|
||||
- One-page checkout form loads
|
||||
|
||||
---
|
||||
|
||||
### Step 6: Add Shipping Info
|
||||
|
||||
**Event:** `add_shipping_info`
|
||||
|
||||
**Purpose:** Track when user selects shipping method
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
document.querySelectorAll('input[name="shipping"]').forEach(function(option) {
|
||||
option.addEventListener('change', function() {
|
||||
var selectedShipping = this.value;
|
||||
var cartItems = getCartItems();
|
||||
var subtotal = calculateSubtotal();
|
||||
var shippingCost = getShippingCost(selectedShipping);
|
||||
var total = subtotal + shippingCost;
|
||||
|
||||
gtag('event', 'add_shipping_info', {
|
||||
'items': cartItems,
|
||||
'value': total,
|
||||
'currency': 'USD',
|
||||
'shipping_tier': selectedShipping // 'standard', 'express', 'overnight'
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
**Shipping Tier Values:**
|
||||
- `standard` - Standard delivery
|
||||
- `express` - Express delivery
|
||||
- `overnight` - Overnight delivery
|
||||
- `pickup` - Store pickup
|
||||
- `free_shipping` - Free shipping option
|
||||
|
||||
**Reporting Use:**
|
||||
- Shipping method selection analysis
|
||||
- Funnel drop-off by shipping option
|
||||
|
||||
---
|
||||
|
||||
### Step 7: Add Payment Info
|
||||
|
||||
**Event:** `add_payment_info`
|
||||
|
||||
**Purpose:** Track when user enters payment information
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
document.getElementById('payment-form').addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var paymentMethod = document.querySelector('input[name="payment"]:checked').value;
|
||||
var cartItems = getCartItems();
|
||||
var totalValue = calculateTotal();
|
||||
|
||||
gtag('event', 'add_payment_info', {
|
||||
'payment_type': paymentMethod,
|
||||
'items': cartItems,
|
||||
'value': totalValue,
|
||||
'currency': 'USD'
|
||||
});
|
||||
|
||||
// Process payment
|
||||
processPayment(paymentMethod);
|
||||
});
|
||||
```
|
||||
|
||||
**Payment Type Values:**
|
||||
- `credit_card`
|
||||
- `debit_card`
|
||||
- `paypal`
|
||||
- `apple_pay`
|
||||
- `google_pay`
|
||||
- `bank_transfer`
|
||||
- `crypto`
|
||||
|
||||
**Reporting Use:**
|
||||
- Payment method distribution
|
||||
- Payment method-to-purchase completion rate
|
||||
|
||||
---
|
||||
|
||||
### Step 8: Purchase (MOST IMPORTANT)
|
||||
|
||||
**Event:** `purchase`
|
||||
|
||||
**Purpose:** Track completed transactions (highest priority event)
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// After payment confirmation
|
||||
function trackPurchase(transactionData) {
|
||||
gtag('event', 'purchase', {
|
||||
'transaction_id': 'TXN_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9),
|
||||
'affiliation': 'Online Store',
|
||||
'value': transactionData.total,
|
||||
'currency': 'USD',
|
||||
'tax': transactionData.tax,
|
||||
'shipping': transactionData.shipping,
|
||||
'coupon': transactionData.coupon || undefined,
|
||||
'items': transactionData.items.map(function(item) {
|
||||
return {
|
||||
'item_id': item.id,
|
||||
'item_name': item.name,
|
||||
'item_category': item.category,
|
||||
'item_brand': item.brand,
|
||||
'item_variant': item.variant,
|
||||
'price': item.price,
|
||||
'quantity': item.quantity,
|
||||
'affiliation': 'Online Store'
|
||||
};
|
||||
})
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
**Transaction ID Requirements:**
|
||||
```
|
||||
✅ GOOD:
|
||||
TXN_1731234567890_abc123def456 // Unique, timestamp-based
|
||||
TXN_20241110_001_ABC123 // Order ID based
|
||||
user_123_purchase_1234567890 // User + timestamp based
|
||||
|
||||
❌ BAD:
|
||||
purchase // Not unique
|
||||
order_123 // Can be reused
|
||||
TXN_12345 // Too short, likely duplicated
|
||||
```
|
||||
|
||||
**Critical Points:**
|
||||
1. **Uniqueness:** Each transaction gets ONE unique ID
|
||||
2. **Non-reusable:** Never use same ID twice
|
||||
3. **Consistency:** Use same ID in all systems (website, backend, reports)
|
||||
4. **Timing:** Send immediately upon payment confirmation
|
||||
5. **Items Array:** Must include all products purchased
|
||||
|
||||
**Backend Implementation (Node.js):**
|
||||
```javascript
|
||||
app.post('/api/purchase', async (req, res) => {
|
||||
const { orderData } = req.body;
|
||||
const transactionId = `TXN_${Date.now()}_${generateRandomString(12)}`;
|
||||
|
||||
// Save order
|
||||
await Order.create({
|
||||
transactionId: transactionId,
|
||||
items: orderData.items,
|
||||
total: orderData.total,
|
||||
// ...
|
||||
});
|
||||
|
||||
// Return transaction ID for client-side tracking
|
||||
res.json({ transactionId: transactionId });
|
||||
});
|
||||
|
||||
// Client receives transaction ID and sends to GA4
|
||||
gtag('event', 'purchase', {
|
||||
'transaction_id': response.transactionId,
|
||||
'items': cartItems,
|
||||
'value': total,
|
||||
'currency': 'USD'
|
||||
});
|
||||
```
|
||||
|
||||
**Reporting Impact:**
|
||||
- Revenue tracking
|
||||
- Transaction count
|
||||
- Google Ads conversion tracking
|
||||
- Attribution modeling
|
||||
- Ecommerce reports
|
||||
- Key Event (automatic)
|
||||
|
||||
---
|
||||
|
||||
### Step 9: Refund (Optional)
|
||||
|
||||
**Event:** `refund`
|
||||
|
||||
**Purpose:** Track refunded purchases
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// When refund is processed
|
||||
gtag('event', 'refund', {
|
||||
'transaction_id': orderData.transactionId, // Same ID as original purchase
|
||||
'value': refundAmount,
|
||||
'currency': 'USD',
|
||||
'items': [
|
||||
{
|
||||
'item_id': 'SKU_123',
|
||||
'quantity': 1 // Quantity refunded
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
**Important:**
|
||||
- Use SAME transaction_id as original purchase
|
||||
- Value is the refund amount
|
||||
- Only include refunded items
|
||||
|
||||
---
|
||||
|
||||
## Multiple Product Variants
|
||||
|
||||
**Scenario:** Product available in multiple sizes/colors
|
||||
|
||||
```javascript
|
||||
// Product: "T-Shirt" available in Blue/Large, Red/Small, etc.
|
||||
|
||||
gtag('event', 'add_to_cart', {
|
||||
'items': [{
|
||||
'item_id': 'SKU_TSHIRT_BLUE_LARGE', // Unique per variant
|
||||
'item_name': 'Blue T-Shirt - Large',
|
||||
'item_category': 'Apparel',
|
||||
'item_variant': 'Blue/Large',
|
||||
'price': 49.99,
|
||||
'quantity': 1
|
||||
}],
|
||||
'value': 49.99,
|
||||
'currency': 'USD'
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Multi-Quantity Purchases
|
||||
|
||||
**Scenario:** Customer buys multiple products in one transaction
|
||||
|
||||
```javascript
|
||||
gtag('event', 'purchase', {
|
||||
'transaction_id': 'TXN_12345678',
|
||||
'value': 329.97,
|
||||
'currency': 'USD',
|
||||
'items': [
|
||||
{
|
||||
'item_id': 'SKU_001',
|
||||
'item_name': 'Product A',
|
||||
'price': 99.99,
|
||||
'quantity': 2 // Two units
|
||||
},
|
||||
{
|
||||
'item_id': 'SKU_002',
|
||||
'item_name': 'Product B',
|
||||
'price': 130.00,
|
||||
'quantity': 1 // One unit
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
**Value Calculation:**
|
||||
- Product A: 99.99 × 2 = 199.98
|
||||
- Product B: 130.00 × 1 = 130.00
|
||||
- Total: 329.98 ✓
|
||||
|
||||
---
|
||||
|
||||
## Coupons and Discounts
|
||||
|
||||
**Scenario:** Customer applies coupon code
|
||||
|
||||
**Single Coupon (Purchase Level):**
|
||||
```javascript
|
||||
gtag('event', 'purchase', {
|
||||
'transaction_id': 'TXN_12345678',
|
||||
'value': 89.99, // Already discounted
|
||||
'currency': 'USD',
|
||||
'coupon': 'SUMMER20', // Coupon code
|
||||
'tax': 5.00,
|
||||
'shipping': 10.00,
|
||||
'items': [{
|
||||
'item_id': 'SKU_001',
|
||||
'item_name': 'Product',
|
||||
'price': 100.00, // Pre-discount price
|
||||
'quantity': 1
|
||||
}]
|
||||
});
|
||||
```
|
||||
|
||||
**Item-Level Coupon:**
|
||||
```javascript
|
||||
gtag('event', 'purchase', {
|
||||
'transaction_id': 'TXN_12345678',
|
||||
'value': 329.97,
|
||||
'currency': 'USD',
|
||||
'items': [
|
||||
{
|
||||
'item_id': 'SKU_001',
|
||||
'item_name': 'Product A',
|
||||
'price': 99.99,
|
||||
'quantity': 2,
|
||||
'coupon': 'SUMMER20', // Item-specific coupon
|
||||
'discount': 20.00 // Discount amount
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Funnel Analysis
|
||||
|
||||
**View the complete ecommerce funnel:**
|
||||
|
||||
```
|
||||
view_item_list → 1000 users (100%)
|
||||
view_item → 450 users (45%)
|
||||
add_to_cart → 120 users (12%)
|
||||
begin_checkout → 95 users (9.5%) ← CRITICAL METRIC
|
||||
purchase → 75 users (7.5%)
|
||||
```
|
||||
|
||||
**Drop-off Points:**
|
||||
- view_item → add_to_cart: 73% drop (improve product pages)
|
||||
- add_to_cart → begin_checkout: 21% drop (simplify cart)
|
||||
- begin_checkout → purchase: 21% drop (optimize checkout)
|
||||
|
||||
---
|
||||
|
||||
## Testing Ecommerce Events
|
||||
|
||||
1. **Product Page:** Verify view_item fires with correct product data
|
||||
2. **Add to Cart:** Check add_to_cart with accurate quantity/price
|
||||
3. **Checkout:** Enable DebugView before begin_checkout
|
||||
4. **Purchase:** Validate transaction_id is unique
|
||||
5. **Items Array:** Confirm all items include item_id or item_name
|
||||
|
||||
**Use DebugView to verify:**
|
||||
```
|
||||
✓ Event name correct (purchase, add_to_cart, etc.)
|
||||
✓ Required parameters present
|
||||
✓ Items array structured correctly
|
||||
✓ Values match actual amounts
|
||||
✓ Transaction ID is unique
|
||||
```
|
||||
542
skills/ga4-recommended-events/references/engagement-events.md
Normal file
542
skills/ga4-recommended-events/references/engagement-events.md
Normal file
@@ -0,0 +1,542 @@
|
||||
# Engagement Events Reference
|
||||
|
||||
## Non-Ecommerce Recommended Events
|
||||
|
||||
This reference covers recommended events for user engagement tracking beyond ecommerce transactions.
|
||||
|
||||
---
|
||||
|
||||
## Authentication Events
|
||||
|
||||
### login
|
||||
|
||||
**Purpose:** Track user login/authentication
|
||||
|
||||
**Parameters:**
|
||||
- `method` (required) - Authentication method used
|
||||
|
||||
**Authentication Methods:**
|
||||
- `email` - Email and password
|
||||
- `phone` - Phone number verification
|
||||
- `social` - Social network login
|
||||
- `google` - Google Sign-in
|
||||
- `facebook` - Facebook Login
|
||||
- `apple` - Apple Sign-in
|
||||
- `microsoft` - Microsoft/Office 365
|
||||
- `saml` - SAML enterprise login
|
||||
- `fingerprint` - Biometric authentication
|
||||
- `password` - Password-only
|
||||
- `sso` - Single sign-on
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
gtag('event', 'login', {
|
||||
'method': 'google'
|
||||
});
|
||||
```
|
||||
|
||||
**Different Authentication Methods:**
|
||||
```javascript
|
||||
// Social login
|
||||
gtag('event', 'login', {
|
||||
'method': 'facebook'
|
||||
});
|
||||
|
||||
// Enterprise SSO
|
||||
gtag('event', 'login', {
|
||||
'method': 'saml'
|
||||
});
|
||||
|
||||
// Biometric
|
||||
gtag('event', 'login', {
|
||||
'method': 'fingerprint'
|
||||
});
|
||||
```
|
||||
|
||||
**Reporting Use:**
|
||||
- User authentication tracking
|
||||
- Auth method effectiveness
|
||||
- Login success/failure analysis
|
||||
- Funnel starting point
|
||||
|
||||
---
|
||||
|
||||
### sign_up
|
||||
|
||||
**Purpose:** Track new account creation
|
||||
|
||||
**Parameters:**
|
||||
- `method` (required) - Registration method
|
||||
|
||||
**Registration Methods:**
|
||||
- `email` - Email registration
|
||||
- `phone` - Phone registration
|
||||
- `social` - Social signup
|
||||
- `google` - Google signup
|
||||
- `facebook` - Facebook signup
|
||||
- `apple` - Apple ID signup
|
||||
- `in_app` - Mobile app signup
|
||||
- `api` - Programmatic signup
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
gtag('event', 'sign_up', {
|
||||
'method': 'email'
|
||||
});
|
||||
```
|
||||
|
||||
**Alternative Signup Methods:**
|
||||
```javascript
|
||||
// Social network signup
|
||||
gtag('event', 'sign_up', {
|
||||
'method': 'apple'
|
||||
});
|
||||
|
||||
// In-app registration
|
||||
gtag('event', 'sign_up', {
|
||||
'method': 'in_app'
|
||||
});
|
||||
```
|
||||
|
||||
**Reporting Use:**
|
||||
- New user acquisition
|
||||
- Registration method performance
|
||||
- Signup funnel analysis
|
||||
- Revenue attribution from signups
|
||||
|
||||
---
|
||||
|
||||
## Content Engagement Events
|
||||
|
||||
### search
|
||||
|
||||
**Purpose:** Track site/app search functionality
|
||||
|
||||
**Parameters:**
|
||||
- `search_term` (required) - What user searched for
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
document.getElementById('search-form').addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
var searchTerm = document.getElementById('search-input').value;
|
||||
|
||||
gtag('event', 'search', {
|
||||
'search_term': searchTerm
|
||||
});
|
||||
|
||||
// Perform search
|
||||
performSearch(searchTerm);
|
||||
});
|
||||
```
|
||||
|
||||
**Advanced Implementation:**
|
||||
```javascript
|
||||
// Track search with result count
|
||||
gtag('event', 'search', {
|
||||
'search_term': 'blue shoes',
|
||||
'search_results_count': 42 // Custom parameter
|
||||
});
|
||||
```
|
||||
|
||||
**Reporting Use:**
|
||||
- Popular search terms
|
||||
- Search-to-purchase analysis
|
||||
- Search effectiveness
|
||||
- Missing products (failed searches)
|
||||
|
||||
**Best Practices:**
|
||||
- Send before results load (immediate)
|
||||
- Don't include user input errors
|
||||
- Standardize term formatting (lowercase)
|
||||
|
||||
---
|
||||
|
||||
### view_item
|
||||
|
||||
**Purpose:** User views product/content detail
|
||||
|
||||
**Parameters:**
|
||||
- `items` (required) - Array with item_id and item_name
|
||||
- `value` (recommended) - Item price
|
||||
- `currency` (recommended) - Currency code
|
||||
|
||||
*See "items-array-reference.md" for complete details*
|
||||
|
||||
---
|
||||
|
||||
### view_item_list
|
||||
|
||||
**Purpose:** User views collection/search results/category
|
||||
|
||||
**Parameters:**
|
||||
- `items` (required) - Array of products
|
||||
- `item_list_id` (recommended) - List identifier
|
||||
- `item_list_name` (recommended) - List name
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// On category page load
|
||||
gtag('event', 'view_item_list', {
|
||||
'items': [
|
||||
{
|
||||
'item_id': 'SKU_001',
|
||||
'item_name': 'Product A',
|
||||
'item_category': 'Electronics'
|
||||
},
|
||||
{
|
||||
'item_id': 'SKU_002',
|
||||
'item_name': 'Product B',
|
||||
'item_category': 'Electronics'
|
||||
}
|
||||
],
|
||||
'item_list_id': 'category_electronics',
|
||||
'item_list_name': 'Electronics Category'
|
||||
});
|
||||
```
|
||||
|
||||
**List Types:**
|
||||
- Category browse
|
||||
- Search results
|
||||
- Featured/homepage
|
||||
- Recommendations
|
||||
- Related products
|
||||
- Best sellers
|
||||
- New arrivals
|
||||
|
||||
---
|
||||
|
||||
### select_item
|
||||
|
||||
**Purpose:** User selects item from list
|
||||
|
||||
**Parameters:**
|
||||
- `items` (required) - Selected item(s)
|
||||
- `item_list_id` (optional) - List identifier
|
||||
- `item_list_name` (optional) - List name
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
document.querySelectorAll('.product-link').forEach(function(link) {
|
||||
link.addEventListener('click', function() {
|
||||
var itemId = this.getAttribute('data-item-id');
|
||||
var itemName = this.getAttribute('data-item-name');
|
||||
|
||||
gtag('event', 'select_item', {
|
||||
'items': [{
|
||||
'item_id': itemId,
|
||||
'item_name': itemName,
|
||||
'item_list_name': 'Search Results'
|
||||
}]
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
**Reporting Use:**
|
||||
- Click-through rate from lists
|
||||
- Product popularity
|
||||
- List effectiveness
|
||||
- Search result performance
|
||||
|
||||
---
|
||||
|
||||
## Promotion Events
|
||||
|
||||
### view_promotion
|
||||
|
||||
**Purpose:** Promotional banner/offer displayed
|
||||
|
||||
**Parameters:**
|
||||
- `promotion_id` (recommended) - Promotion identifier
|
||||
- `promotion_name` (recommended) - Promotion name
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// On promotion banner visible
|
||||
gtag('event', 'view_promotion', {
|
||||
'promotion_id': 'SUMMER_SALE_2024',
|
||||
'promotion_name': '50% Off Summer Sale'
|
||||
});
|
||||
```
|
||||
|
||||
**Reporting Use:**
|
||||
- Promotion impressions
|
||||
- Banner effectiveness
|
||||
- Which promotions drive traffic
|
||||
|
||||
---
|
||||
|
||||
### select_promotion
|
||||
|
||||
**Purpose:** User clicks promotion
|
||||
|
||||
**Parameters:**
|
||||
- `promotion_id` (recommended) - Promotion identifier
|
||||
- `promotion_name` (recommended) - Promotion name
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
document.querySelector('.promotion-banner').addEventListener('click', function() {
|
||||
gtag('event', 'select_promotion', {
|
||||
'promotion_id': 'SUMMER_SALE_2024',
|
||||
'promotion_name': '50% Off Summer Sale'
|
||||
});
|
||||
|
||||
// Navigate to sale
|
||||
window.location.href = '/sale';
|
||||
});
|
||||
```
|
||||
|
||||
**Reporting Use:**
|
||||
- Promotion click rates
|
||||
- Promotion-to-purchase funnel
|
||||
- CTR by promotion type
|
||||
|
||||
---
|
||||
|
||||
## Sharing and Social Events
|
||||
|
||||
### share
|
||||
|
||||
**Purpose:** User shares content
|
||||
|
||||
**Parameters:**
|
||||
- `method` (optional) - Share method
|
||||
- `content_type` (optional) - Type of content
|
||||
- `item_id` (optional) - Content identifier
|
||||
|
||||
**Share Methods:**
|
||||
- `email`
|
||||
- `facebook`
|
||||
- `twitter`
|
||||
- `whatsapp`
|
||||
- `sms`
|
||||
- `copy_link`
|
||||
- `print`
|
||||
- `native` (iOS share sheet)
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// Email share
|
||||
document.getElementById('email-share-btn').addEventListener('click', function() {
|
||||
gtag('event', 'share', {
|
||||
'method': 'email',
|
||||
'content_type': 'product',
|
||||
'item_id': 'SKU_123'
|
||||
});
|
||||
});
|
||||
|
||||
// Social share
|
||||
document.getElementById('facebook-share-btn').addEventListener('click', function() {
|
||||
gtag('event', 'share', {
|
||||
'method': 'facebook',
|
||||
'content_type': 'article',
|
||||
'item_id': 'article_456'
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
**Reporting Use:**
|
||||
- Content virality
|
||||
- Share method preferences
|
||||
- Shared content performance
|
||||
|
||||
---
|
||||
|
||||
### join_group
|
||||
|
||||
**Purpose:** User joins group/team/community
|
||||
|
||||
**Parameters:**
|
||||
- `group_id` (optional) - Group identifier
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
gtag('event', 'join_group', {
|
||||
'group_id': 'premium_members'
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Interaction Events
|
||||
|
||||
### select_content
|
||||
|
||||
**Purpose:** User selects specific content
|
||||
|
||||
**Parameters:**
|
||||
- `content_type` (optional) - Content type
|
||||
- `item_id` (optional) - Content identifier
|
||||
|
||||
**Content Types:**
|
||||
- `product`
|
||||
- `article`
|
||||
- `video`
|
||||
- `audio`
|
||||
- `image`
|
||||
- `document`
|
||||
- `app`
|
||||
- `game`
|
||||
- `course`
|
||||
- `lesson`
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// Video selection
|
||||
gtag('event', 'select_content', {
|
||||
'content_type': 'video',
|
||||
'item_id': 'video_123'
|
||||
});
|
||||
|
||||
// Article selection
|
||||
gtag('event', 'select_content', {
|
||||
'content_type': 'article',
|
||||
'item_id': 'article_456'
|
||||
});
|
||||
|
||||
// Course lesson
|
||||
gtag('event', 'select_content', {
|
||||
'content_type': 'lesson',
|
||||
'item_id': 'lesson_789'
|
||||
});
|
||||
```
|
||||
|
||||
**Reporting Use:**
|
||||
- Content popularity
|
||||
- Content engagement patterns
|
||||
- Most viewed content
|
||||
|
||||
---
|
||||
|
||||
## Lead Generation Events
|
||||
|
||||
### generate_lead
|
||||
|
||||
**Purpose:** Track lead generation (form submission, quote request, etc.)
|
||||
|
||||
**Parameters:**
|
||||
- `value` (optional) - Estimated lead value
|
||||
- `currency` (optional) - Currency code
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// Contact form submission
|
||||
document.getElementById('contact-form').addEventListener('submit', function() {
|
||||
gtag('event', 'generate_lead', {
|
||||
'value': 0, // No monetary value
|
||||
'currency': 'USD'
|
||||
});
|
||||
});
|
||||
|
||||
// Demo request (estimate value)
|
||||
gtag('event', 'generate_lead', {
|
||||
'value': 500.00, // Estimated annual value
|
||||
'currency': 'USD'
|
||||
});
|
||||
|
||||
// Enterprise trial (higher value)
|
||||
gtag('event', 'generate_lead', {
|
||||
'value': 5000.00,
|
||||
'currency': 'USD'
|
||||
});
|
||||
```
|
||||
|
||||
**Lead Types:**
|
||||
- Contact form
|
||||
- Demo request
|
||||
- Consultation booking
|
||||
- Newsletter signup
|
||||
- Free trial
|
||||
- Quote request
|
||||
- Job application
|
||||
- Event registration
|
||||
|
||||
**Reporting Use:**
|
||||
- Lead generation funnel
|
||||
- Lead value attribution
|
||||
- Form effectiveness
|
||||
- Lead source comparison
|
||||
|
||||
---
|
||||
|
||||
## Measurement Guidelines
|
||||
|
||||
### When to Send Events
|
||||
|
||||
**Immediate Trigger:**
|
||||
- User action completes (click, form submit)
|
||||
- Content becomes visible (on page load)
|
||||
- User selects item
|
||||
|
||||
**Don't Wait For:**
|
||||
- Backend confirmation
|
||||
- Page navigation
|
||||
- API response (unless critical)
|
||||
|
||||
**Implementation Pattern:**
|
||||
```javascript
|
||||
// ❌ WRONG: Wait for confirmation
|
||||
function handleAction() {
|
||||
performAction().then(function() {
|
||||
gtag('event', 'some_event'); // Too late
|
||||
});
|
||||
}
|
||||
|
||||
// ✅ CORRECT: Fire immediately
|
||||
function handleAction() {
|
||||
gtag('event', 'some_event'); // Fire now
|
||||
performAction(); // Then execute
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Event Parameter Summary
|
||||
|
||||
| Event | Required Params | Recommended Params | Optional |
|
||||
|-------|---|---|---|
|
||||
| login | method | - | - |
|
||||
| sign_up | method | - | - |
|
||||
| search | search_term | - | - |
|
||||
| view_item | items | value, currency | - |
|
||||
| view_item_list | items | item_list_id, item_list_name | - |
|
||||
| select_item | items | item_list_id, item_list_name | - |
|
||||
| view_promotion | - | promotion_id, promotion_name | - |
|
||||
| select_promotion | - | promotion_id, promotion_name | - |
|
||||
| share | - | method, content_type, item_id | - |
|
||||
| generate_lead | - | value, currency | - |
|
||||
| select_content | - | content_type, item_id | - |
|
||||
|
||||
---
|
||||
|
||||
## Testing Engagement Events
|
||||
|
||||
**Use DebugView to Verify:**
|
||||
|
||||
1. **Login Event**
|
||||
- Check `method` parameter populated
|
||||
- Verify on successful authentication
|
||||
|
||||
2. **Search Event**
|
||||
- Confirm `search_term` is present
|
||||
- Check on form submission
|
||||
|
||||
3. **View Item**
|
||||
- Verify items array structure
|
||||
- Check price and currency
|
||||
|
||||
4. **Content Selection**
|
||||
- Ensure item_id or content_type present
|
||||
- Verify on user click
|
||||
|
||||
**Debug Checklist:**
|
||||
```
|
||||
✓ Event fires at correct time
|
||||
✓ Parameters match specifications
|
||||
✓ Parameter values are accurate
|
||||
✓ Event name spelled correctly
|
||||
✓ No duplicate events
|
||||
✓ Values are appropriate data type
|
||||
```
|
||||
@@ -0,0 +1,711 @@
|
||||
# Implementation Examples
|
||||
|
||||
## Real-World Code Examples
|
||||
|
||||
Complete, production-ready examples for implementing recommended events.
|
||||
|
||||
---
|
||||
|
||||
## Example 1: E-commerce Product Page (React)
|
||||
|
||||
**File:** `ProductPage.jsx`
|
||||
|
||||
```javascript
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { gtag } from './analytics-utils';
|
||||
|
||||
export function ProductPage({ productId }) {
|
||||
const [product, setProduct] = useState(null);
|
||||
const [quantity, setQuantity] = useState(1);
|
||||
|
||||
useEffect(() => {
|
||||
// Fetch product data
|
||||
fetchProduct(productId).then(product => {
|
||||
setProduct(product);
|
||||
|
||||
// Track view_item when product loads
|
||||
gtag('event', 'view_item', {
|
||||
'items': [{
|
||||
'item_id': product.sku,
|
||||
'item_name': product.name,
|
||||
'item_category': product.category,
|
||||
'item_brand': product.brand,
|
||||
'item_variant': `${product.color}/${product.size}`,
|
||||
'price': product.price,
|
||||
'quantity': 1
|
||||
}],
|
||||
'value': product.price,
|
||||
'currency': 'USD'
|
||||
});
|
||||
});
|
||||
}, [productId]);
|
||||
|
||||
const handleAddToCart = () => {
|
||||
if (!product) return;
|
||||
|
||||
gtag('event', 'add_to_cart', {
|
||||
'items': [{
|
||||
'item_id': product.sku,
|
||||
'item_name': product.name,
|
||||
'item_category': product.category,
|
||||
'price': product.price,
|
||||
'quantity': quantity
|
||||
}],
|
||||
'value': product.price * quantity,
|
||||
'currency': 'USD'
|
||||
});
|
||||
|
||||
addToCart(product.id, quantity);
|
||||
// Show confirmation
|
||||
};
|
||||
|
||||
if (!product) return <div>Loading...</div>;
|
||||
|
||||
return (
|
||||
<div className="product-page">
|
||||
<h1>{product.name}</h1>
|
||||
<p>Price: ${product.price}</p>
|
||||
<input
|
||||
type="number"
|
||||
min="1"
|
||||
value={quantity}
|
||||
onChange={(e) => setQuantity(parseInt(e.target.value))}
|
||||
/>
|
||||
<button onClick={handleAddToCart}>Add to Cart</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Example 2: Checkout Flow (Vanilla JavaScript)
|
||||
|
||||
**File:** `checkout.js`
|
||||
|
||||
```javascript
|
||||
// Checkout page - tracks the entire funnel
|
||||
|
||||
class CheckoutFlow {
|
||||
constructor() {
|
||||
this.cart = getCartFromStorage();
|
||||
this.initializeListeners();
|
||||
}
|
||||
|
||||
initializeListeners() {
|
||||
// Begin checkout button
|
||||
document.getElementById('begin-checkout-btn')
|
||||
.addEventListener('click', () => this.handleBeginCheckout());
|
||||
|
||||
// Shipping method selection
|
||||
document.querySelectorAll('input[name="shipping"]')
|
||||
.forEach(el => el.addEventListener('change', (e) => this.handleShippingSelect(e)));
|
||||
|
||||
// Payment method selection
|
||||
document.querySelectorAll('input[name="payment"]')
|
||||
.forEach(el => el.addEventListener('change', (e) => this.handlePaymentSelect(e)));
|
||||
|
||||
// Checkout form submission
|
||||
document.getElementById('checkout-form')
|
||||
.addEventListener('submit', (e) => this.handleCheckoutSubmit(e));
|
||||
}
|
||||
|
||||
handleBeginCheckout() {
|
||||
const cartData = this.getCartData();
|
||||
|
||||
gtag('event', 'begin_checkout', {
|
||||
'items': cartData.items,
|
||||
'value': cartData.total,
|
||||
'currency': 'USD',
|
||||
'coupon': cartData.coupon || undefined
|
||||
});
|
||||
|
||||
// Navigate to checkout step 1
|
||||
navigateToCheckoutStep(1);
|
||||
}
|
||||
|
||||
handleShippingSelect(event) {
|
||||
const shippingMethod = event.target.value;
|
||||
const cartData = this.getCartData();
|
||||
const shippingCost = this.calculateShipping(shippingMethod);
|
||||
|
||||
gtag('event', 'add_shipping_info', {
|
||||
'items': cartData.items,
|
||||
'value': cartData.subtotal + shippingCost,
|
||||
'currency': 'USD',
|
||||
'shipping_tier': shippingMethod
|
||||
});
|
||||
}
|
||||
|
||||
handlePaymentSelect(event) {
|
||||
const paymentMethod = event.target.value;
|
||||
const cartData = this.getCartData();
|
||||
const total = this.calculateTotal();
|
||||
|
||||
gtag('event', 'add_payment_info', {
|
||||
'payment_type': paymentMethod,
|
||||
'items': cartData.items,
|
||||
'value': total,
|
||||
'currency': 'USD'
|
||||
});
|
||||
}
|
||||
|
||||
handleCheckoutSubmit(event) {
|
||||
event.preventDefault();
|
||||
|
||||
// Process payment (returns transaction ID)
|
||||
processPayment(this.getFormData())
|
||||
.then(response => {
|
||||
this.trackPurchase(response);
|
||||
this.handlePurchaseSuccess(response);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Payment failed:', error);
|
||||
});
|
||||
}
|
||||
|
||||
trackPurchase(paymentResponse) {
|
||||
const cartData = this.getCartData();
|
||||
const orderTotal = paymentResponse.amount;
|
||||
|
||||
gtag('event', 'purchase', {
|
||||
'transaction_id': paymentResponse.transactionId,
|
||||
'affiliation': 'Online Store',
|
||||
'value': orderTotal,
|
||||
'currency': 'USD',
|
||||
'tax': paymentResponse.tax || 0,
|
||||
'shipping': paymentResponse.shipping || 0,
|
||||
'coupon': cartData.coupon || undefined,
|
||||
'items': cartData.items.map(item => ({
|
||||
'item_id': item.sku,
|
||||
'item_name': item.name,
|
||||
'item_category': item.category,
|
||||
'item_brand': item.brand,
|
||||
'item_variant': item.variant,
|
||||
'price': item.price,
|
||||
'quantity': item.quantity,
|
||||
'affiliation': 'Online Store'
|
||||
}))
|
||||
});
|
||||
}
|
||||
|
||||
getCartData() {
|
||||
const cart = getCartFromStorage();
|
||||
const items = [];
|
||||
let total = 0;
|
||||
|
||||
cart.items.forEach(item => {
|
||||
const itemTotal = item.price * item.quantity;
|
||||
total += itemTotal;
|
||||
|
||||
items.push({
|
||||
'item_id': item.sku,
|
||||
'item_name': item.name,
|
||||
'item_category': item.category,
|
||||
'price': item.price,
|
||||
'quantity': item.quantity
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
items: items,
|
||||
subtotal: total,
|
||||
coupon: cart.coupon || null,
|
||||
total: total
|
||||
};
|
||||
}
|
||||
|
||||
calculateTotal() {
|
||||
const cartData = this.getCartData();
|
||||
const shippingMethod = document.querySelector('input[name="shipping"]:checked').value;
|
||||
const shipping = this.calculateShipping(shippingMethod);
|
||||
const tax = cartData.subtotal * 0.08; // 8% tax example
|
||||
|
||||
return cartData.subtotal + shipping + tax;
|
||||
}
|
||||
|
||||
calculateShipping(method) {
|
||||
const shipping = {
|
||||
'standard': 10.00,
|
||||
'express': 25.00,
|
||||
'overnight': 50.00,
|
||||
'pickup': 0.00
|
||||
};
|
||||
return shipping[method] || 10.00;
|
||||
}
|
||||
|
||||
handlePurchaseSuccess(response) {
|
||||
// Clear cart, show thank you page
|
||||
clearCart();
|
||||
window.location.href = `/thank-you?order=${response.orderId}`;
|
||||
}
|
||||
|
||||
getFormData() {
|
||||
return {
|
||||
email: document.getElementById('email').value,
|
||||
shipping_address: document.getElementById('address').value,
|
||||
payment_method: document.querySelector('input[name="payment"]:checked').value,
|
||||
coupon: document.getElementById('coupon').value || null
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize on page load
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
new CheckoutFlow();
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Example 3: Google Tag Manager Setup
|
||||
|
||||
**GTM Configuration - GA4 Configuration Tag**
|
||||
|
||||
```
|
||||
Tag Name: GA4 - Configuration
|
||||
Tag Type: Google Tag
|
||||
Measurement ID: G-XXXXXXXXXX
|
||||
|
||||
Configuration Settings:
|
||||
- Allow Google Signals: true
|
||||
- Allow ad personalization signals: true
|
||||
|
||||
Triggering:
|
||||
- Trigger: Initialization - All Pages
|
||||
```
|
||||
|
||||
**GTM - Add to Cart Event Tag**
|
||||
|
||||
```
|
||||
Tag Name: GA4 - Add to Cart
|
||||
Tag Type: Google Tag
|
||||
Measurement ID: G-XXXXXXXXXX
|
||||
|
||||
Event Name: add_to_cart
|
||||
|
||||
Event Parameters:
|
||||
├── items (variable): {{DL - Cart Items}}
|
||||
├── value (variable): {{DL - Cart Total}}
|
||||
└── currency (constant): USD
|
||||
|
||||
Triggering:
|
||||
- Trigger: Custom Event "addToCart"
|
||||
```
|
||||
|
||||
**GTM - Purchase Event Tag**
|
||||
|
||||
```
|
||||
Tag Name: GA4 - Purchase
|
||||
Tag Type: Google Tag
|
||||
Measurement ID: G-XXXXXXXXXX
|
||||
|
||||
Event Name: purchase
|
||||
|
||||
Event Parameters:
|
||||
├── transaction_id (variable): {{DL - Transaction ID}}
|
||||
├── value (variable): {{DL - Order Total}}
|
||||
├── currency (constant): USD
|
||||
├── items (variable): {{DL - Purchase Items}}
|
||||
├── tax (variable): {{DL - Tax Amount}}
|
||||
├── shipping (variable): {{DL - Shipping Cost}}
|
||||
└── coupon (variable): {{DL - Coupon Code}}
|
||||
|
||||
Triggering:
|
||||
- Trigger: Custom Event "purchase"
|
||||
```
|
||||
|
||||
**Data Layer Push (Website Code)**
|
||||
|
||||
```javascript
|
||||
// When user clicks add to cart
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
dataLayer.push({
|
||||
'event': 'addToCart',
|
||||
'cart_items': [{
|
||||
'item_id': 'SKU_123',
|
||||
'item_name': 'Product Name',
|
||||
'price': 99.99,
|
||||
'quantity': 1
|
||||
}],
|
||||
'cart_total': 99.99
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Example 4: Login Event Implementation
|
||||
|
||||
**File:** `auth.js`
|
||||
|
||||
```javascript
|
||||
class AuthenticationManager {
|
||||
async loginWithEmail(email, password) {
|
||||
try {
|
||||
const response = await fetch('/api/login', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, password })
|
||||
});
|
||||
|
||||
const user = await response.json();
|
||||
|
||||
// Track login event
|
||||
gtag('event', 'login', {
|
||||
'method': 'email'
|
||||
});
|
||||
|
||||
// Set user properties
|
||||
gtag('set', {
|
||||
'user_id': 'user_' + user.id,
|
||||
'customer_segment': user.subscription_tier
|
||||
});
|
||||
|
||||
// Store session
|
||||
this.storeSession(user);
|
||||
return user;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Login failed:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async loginWithGoogle(googleToken) {
|
||||
try {
|
||||
const response = await fetch('/api/login/google', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ token: googleToken })
|
||||
});
|
||||
|
||||
const user = await response.json();
|
||||
|
||||
gtag('event', 'login', {
|
||||
'method': 'google'
|
||||
});
|
||||
|
||||
gtag('set', {
|
||||
'user_id': 'user_' + user.id
|
||||
});
|
||||
|
||||
this.storeSession(user);
|
||||
return user;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Google login failed:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async signup(email, password) {
|
||||
try {
|
||||
const response = await fetch('/api/signup', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, password })
|
||||
});
|
||||
|
||||
const user = await response.json();
|
||||
|
||||
gtag('event', 'sign_up', {
|
||||
'method': 'email'
|
||||
});
|
||||
|
||||
gtag('set', {
|
||||
'user_id': 'user_' + user.id
|
||||
});
|
||||
|
||||
this.storeSession(user);
|
||||
return user;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Signup failed:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
logout() {
|
||||
// Clear user identification
|
||||
gtag('set', {
|
||||
'user_id': null
|
||||
});
|
||||
|
||||
// Clear session
|
||||
this.clearSession();
|
||||
window.location.href = '/';
|
||||
}
|
||||
|
||||
storeSession(user) {
|
||||
sessionStorage.setItem('user', JSON.stringify(user));
|
||||
}
|
||||
|
||||
clearSession() {
|
||||
sessionStorage.removeItem('user');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Example 5: Search Event with Results
|
||||
|
||||
**File:** `search.js`
|
||||
|
||||
```javascript
|
||||
class SearchManager {
|
||||
constructor() {
|
||||
this.setupSearchListener();
|
||||
}
|
||||
|
||||
setupSearchListener() {
|
||||
const searchForm = document.getElementById('search-form');
|
||||
if (searchForm) {
|
||||
searchForm.addEventListener('submit', (e) => this.handleSearch(e));
|
||||
}
|
||||
}
|
||||
|
||||
async handleSearch(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const searchTerm = document.getElementById('search-input').value;
|
||||
|
||||
if (!searchTerm.trim()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Track search immediately
|
||||
gtag('event', 'search', {
|
||||
'search_term': searchTerm
|
||||
});
|
||||
|
||||
// Fetch results
|
||||
try {
|
||||
const results = await this.fetchSearchResults(searchTerm);
|
||||
this.displayResults(results, searchTerm);
|
||||
} catch (error) {
|
||||
console.error('Search failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
displayResults(results, searchTerm) {
|
||||
// Track view_item_list for search results
|
||||
if (results.length > 0) {
|
||||
gtag('event', 'view_item_list', {
|
||||
'items': results.slice(0, 20).map(product => ({
|
||||
'item_id': product.sku,
|
||||
'item_name': product.name,
|
||||
'item_category': product.category,
|
||||
'price': product.price,
|
||||
'index': results.indexOf(product)
|
||||
})),
|
||||
'item_list_id': 'search_results',
|
||||
'item_list_name': `Search Results for "${searchTerm}"`
|
||||
});
|
||||
}
|
||||
|
||||
// Render search results UI
|
||||
this.renderResultsPage(results, searchTerm);
|
||||
}
|
||||
|
||||
async fetchSearchResults(term) {
|
||||
const response = await fetch(`/api/search?q=${encodeURIComponent(term)}`);
|
||||
return response.json();
|
||||
}
|
||||
|
||||
renderResultsPage(results, term) {
|
||||
// Render results to DOM
|
||||
const resultsContainer = document.getElementById('search-results');
|
||||
resultsContainer.innerHTML = '';
|
||||
|
||||
if (results.length === 0) {
|
||||
resultsContainer.innerHTML = '<p>No results found</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
results.forEach((product, index) => {
|
||||
const productEl = this.createProductElement(product, index);
|
||||
resultsContainer.appendChild(productEl);
|
||||
|
||||
// Track select_item when user clicks product
|
||||
productEl.addEventListener('click', () => {
|
||||
gtag('event', 'select_item', {
|
||||
'items': [{
|
||||
'item_id': product.sku,
|
||||
'item_name': product.name,
|
||||
'item_list_name': `Search Results for "${term}"`
|
||||
}],
|
||||
'index': index
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
createProductElement(product, index) {
|
||||
const el = document.createElement('div');
|
||||
el.className = 'search-result';
|
||||
el.innerHTML = `
|
||||
<a href="/product/${product.id}">
|
||||
<h3>${product.name}</h3>
|
||||
<p class="price">$${product.price}</p>
|
||||
</a>
|
||||
`;
|
||||
return el;
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
new SearchManager();
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Example 6: Lead Generation Form
|
||||
|
||||
**File:** `lead-form.js`
|
||||
|
||||
```javascript
|
||||
class LeadForm {
|
||||
constructor() {
|
||||
this.setupFormListener();
|
||||
}
|
||||
|
||||
setupFormListener() {
|
||||
const form = document.getElementById('demo-request-form');
|
||||
if (form) {
|
||||
form.addEventListener('submit', (e) => this.handleSubmit(e));
|
||||
}
|
||||
}
|
||||
|
||||
async handleSubmit(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const formData = {
|
||||
name: document.getElementById('name').value,
|
||||
email: document.getElementById('email').value,
|
||||
company: document.getElementById('company').value,
|
||||
phone: document.getElementById('phone').value
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/leads', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(formData)
|
||||
});
|
||||
|
||||
const lead = await response.json();
|
||||
|
||||
// Track lead generation
|
||||
gtag('event', 'generate_lead', {
|
||||
'value': 500.00, // Estimated lead value
|
||||
'currency': 'USD'
|
||||
});
|
||||
|
||||
// Show success message
|
||||
this.showSuccessMessage(lead);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Form submission failed:', error);
|
||||
this.showErrorMessage();
|
||||
}
|
||||
}
|
||||
|
||||
showSuccessMessage(lead) {
|
||||
document.getElementById('demo-request-form').style.display = 'none';
|
||||
document.getElementById('success-message').style.display = 'block';
|
||||
}
|
||||
|
||||
showErrorMessage() {
|
||||
alert('There was an error submitting your request. Please try again.');
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
new LeadForm();
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Example 7: Promotion Tracking
|
||||
|
||||
**File:** `promotions.js`
|
||||
|
||||
```javascript
|
||||
class PromotionTracker {
|
||||
constructor() {
|
||||
this.trackVisiblePromotions();
|
||||
this.setupPromotionClicks();
|
||||
}
|
||||
|
||||
trackVisiblePromotions() {
|
||||
// Track when promotions become visible
|
||||
const promotions = document.querySelectorAll('.promotion-banner');
|
||||
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
const promo = entry.target;
|
||||
const promotionId = promo.getAttribute('data-promo-id');
|
||||
const promotionName = promo.getAttribute('data-promo-name');
|
||||
|
||||
gtag('event', 'view_promotion', {
|
||||
'promotion_id': promotionId,
|
||||
'promotion_name': promotionName
|
||||
});
|
||||
|
||||
// Unobserve after tracking
|
||||
observer.unobserve(promo);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
promotions.forEach(promo => observer.observe(promo));
|
||||
}
|
||||
|
||||
setupPromotionClicks() {
|
||||
document.querySelectorAll('.promotion-banner').forEach(banner => {
|
||||
const link = banner.querySelector('a');
|
||||
if (link) {
|
||||
link.addEventListener('click', (e) => {
|
||||
const promotionId = banner.getAttribute('data-promo-id');
|
||||
const promotionName = banner.getAttribute('data-promo-name');
|
||||
|
||||
gtag('event', 'select_promotion', {
|
||||
'promotion_id': promotionId,
|
||||
'promotion_name': promotionName
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
new PromotionTracker();
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing These Examples
|
||||
|
||||
**Use DebugView to verify:**
|
||||
|
||||
1. Check event names are correct
|
||||
2. Verify all required parameters present
|
||||
3. Validate parameter data types (numbers vs strings)
|
||||
4. Ensure items arrays are properly structured
|
||||
5. Confirm transaction IDs are unique
|
||||
6. Test complete user journeys
|
||||
|
||||
**Example Test Flow:**
|
||||
```
|
||||
1. View product page → verify view_item event
|
||||
2. Add to cart → verify add_to_cart with correct value
|
||||
3. Go to checkout → verify begin_checkout
|
||||
4. Complete purchase → verify purchase with unique transaction_id
|
||||
5. Check DebugView → all events firing with correct parameters
|
||||
```
|
||||
@@ -0,0 +1,677 @@
|
||||
# Items Array Complete Reference
|
||||
|
||||
## Items Array Overview
|
||||
|
||||
The `items` array is a core component of ecommerce tracking in GA4. It appears in all ecommerce events and contains product-level data.
|
||||
|
||||
---
|
||||
|
||||
## Array Structure
|
||||
|
||||
```javascript
|
||||
'items': [
|
||||
{
|
||||
// Required (at least one)
|
||||
'item_id': 'SKU_123',
|
||||
'item_name': 'Product Name',
|
||||
|
||||
// Highly Recommended
|
||||
'price': 99.99,
|
||||
'quantity': 1,
|
||||
'item_category': 'Electronics',
|
||||
|
||||
// Optional
|
||||
'item_brand': 'Brand Name',
|
||||
'item_variant': 'Blue/Large',
|
||||
'item_category2': 'Phones',
|
||||
'item_category3': 'Smartphones',
|
||||
'item_category4': 'Android',
|
||||
'item_category5': 'Flagship',
|
||||
'coupon': 'SUMMER20',
|
||||
'discount': 10.00,
|
||||
'affiliation': 'Online Store',
|
||||
'item_list_id': 'new_arrivals',
|
||||
'item_list_name': 'New Arrivals',
|
||||
'location_id': 'store_123',
|
||||
'index': 0
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Field Details
|
||||
|
||||
### item_id (REQUIRED - at least one)
|
||||
|
||||
**Purpose:** Unique product identifier
|
||||
|
||||
**Format:** String (any format)
|
||||
|
||||
**Examples:**
|
||||
- `SKU_12345`
|
||||
- `PROD_ABC123`
|
||||
- `isbn_9781234567890`
|
||||
- `gtin_1234567890123`
|
||||
|
||||
**Best Practices:**
|
||||
- Use consistent format across all events
|
||||
- Match your internal product database ID
|
||||
- Never include user-specific data
|
||||
|
||||
```javascript
|
||||
'item_id': 'SKU_BLUE_TSHIRT_LARGE'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### item_name (REQUIRED - at least one)
|
||||
|
||||
**Purpose:** Product display name
|
||||
|
||||
**Format:** String (max 100 characters recommended)
|
||||
|
||||
**Examples:**
|
||||
- `Blue T-Shirt`
|
||||
- `Premium Wireless Headphones - Black`
|
||||
- `Winter Jacket - Size M`
|
||||
|
||||
**Best Practices:**
|
||||
- Use human-readable name
|
||||
- Include variant information if not separate
|
||||
- Consistent across ecommerce platform
|
||||
|
||||
```javascript
|
||||
'item_name': 'Blue T-Shirt - Large'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### price (HIGHLY RECOMMENDED)
|
||||
|
||||
**Purpose:** Individual unit price
|
||||
|
||||
**Format:** Number (decimal)
|
||||
|
||||
**Important:**
|
||||
- Per-unit price, NOT total
|
||||
- Total = price × quantity
|
||||
- Should match product catalog price
|
||||
|
||||
```javascript
|
||||
'price': 99.99
|
||||
```
|
||||
|
||||
**Multi-Item Example:**
|
||||
```javascript
|
||||
'items': [
|
||||
{
|
||||
'item_id': 'SKU_001',
|
||||
'item_name': 'Product A',
|
||||
'price': 99.99,
|
||||
'quantity': 2 // Total for this item: 199.98
|
||||
},
|
||||
{
|
||||
'item_id': 'SKU_002',
|
||||
'item_name': 'Product B',
|
||||
'price': 50.00,
|
||||
'quantity': 1 // Total for this item: 50.00
|
||||
}
|
||||
// Grand total: 249.98
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### quantity (HIGHLY RECOMMENDED)
|
||||
|
||||
**Purpose:** Number of units
|
||||
|
||||
**Format:** Integer
|
||||
|
||||
**Examples:**
|
||||
- `1` - Single item
|
||||
- `2` - Two units
|
||||
- `10` - Ten units
|
||||
|
||||
**Important:**
|
||||
- Should be ≥ 1
|
||||
- Impacts value calculations
|
||||
- Should match cart quantity
|
||||
|
||||
```javascript
|
||||
'quantity': 3
|
||||
```
|
||||
|
||||
**Calculation Example:**
|
||||
```
|
||||
price: 99.99
|
||||
quantity: 3
|
||||
item_total: 99.99 × 3 = 299.97
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### item_category (HIGHLY RECOMMENDED)
|
||||
|
||||
**Purpose:** Primary product category
|
||||
|
||||
**Format:** String (e.g., "Electronics", "Apparel", "Home & Garden")
|
||||
|
||||
**Best Practices:**
|
||||
- Use main category only
|
||||
- Keep consistent across platform
|
||||
- Use hierarchical category structure
|
||||
|
||||
```javascript
|
||||
'item_category': 'Electronics'
|
||||
```
|
||||
|
||||
**GA4 Reporting:**
|
||||
- Enables "Items by category" analysis
|
||||
- Product category segments
|
||||
- Category-level conversion rates
|
||||
|
||||
---
|
||||
|
||||
### item_brand (OPTIONAL)
|
||||
|
||||
**Purpose:** Brand/manufacturer
|
||||
|
||||
**Format:** String
|
||||
|
||||
**Examples:**
|
||||
- `Nike`
|
||||
- `Sony`
|
||||
- `Apple`
|
||||
- `Our Store Brand`
|
||||
|
||||
```javascript
|
||||
'item_brand': 'Nike'
|
||||
```
|
||||
|
||||
**Reporting Use:**
|
||||
- Brand performance analysis
|
||||
- Brand-specific conversion rates
|
||||
- Brand preference trends
|
||||
|
||||
---
|
||||
|
||||
### item_variant (OPTIONAL)
|
||||
|
||||
**Purpose:** Product variant (size, color, style, etc.)
|
||||
|
||||
**Format:** String (describe the specific variant)
|
||||
|
||||
**Examples:**
|
||||
- `Blue/Large`
|
||||
- `Red/Medium/Cotton`
|
||||
- `Gold/64GB`
|
||||
- `Leather/Black/Premium`
|
||||
|
||||
**Best Practices:**
|
||||
- Standardize format (Color/Size)
|
||||
- Separate multiple variants with slash
|
||||
- Match product catalog variant descriptions
|
||||
|
||||
```javascript
|
||||
'item_variant': 'Blue/Large/Cotton'
|
||||
```
|
||||
|
||||
**Reporting Use:**
|
||||
- Variant popularity analysis
|
||||
- Which sizes/colors sell best
|
||||
- Variant conversion rates
|
||||
|
||||
---
|
||||
|
||||
### item_category2 through item_category5 (OPTIONAL)
|
||||
|
||||
**Purpose:** Hierarchical category levels
|
||||
|
||||
**Format:** String
|
||||
|
||||
**Examples:**
|
||||
|
||||
**Level Structure:**
|
||||
```
|
||||
item_category: 'Electronics' (Main category)
|
||||
item_category2: 'Audio' (Subcategory)
|
||||
item_category3: 'Headphones' (Sub-subcategory)
|
||||
item_category4: 'Wireless' (Further specification)
|
||||
item_category5: 'Premium' (Additional tier)
|
||||
```
|
||||
|
||||
**Full Example:**
|
||||
```javascript
|
||||
'item_id': 'SKU_HEADPHONE_001',
|
||||
'item_name': 'Premium Wireless Headphones',
|
||||
'item_category': 'Electronics',
|
||||
'item_category2': 'Audio',
|
||||
'item_category3': 'Headphones',
|
||||
'item_category4': 'Wireless',
|
||||
'item_category5': 'Over-Ear'
|
||||
```
|
||||
|
||||
**Another Example:**
|
||||
```javascript
|
||||
'item_category': 'Apparel',
|
||||
'item_category2': 'Mens',
|
||||
'item_category3': 'Shirts',
|
||||
'item_category4': 'T-Shirts',
|
||||
'item_category5': 'Short-Sleeve'
|
||||
```
|
||||
|
||||
**Reporting Use:**
|
||||
- Multi-level category analysis
|
||||
- Category-to-purchase funnel
|
||||
- Detailed product segmentation
|
||||
|
||||
---
|
||||
|
||||
### coupon (OPTIONAL)
|
||||
|
||||
**Purpose:** Coupon/promotion code applied to item
|
||||
|
||||
**Format:** String (coupon code)
|
||||
|
||||
**Examples:**
|
||||
- `SUMMER20`
|
||||
- `SAVE10`
|
||||
- `WELCOME5`
|
||||
- `NEWYEAR50`
|
||||
|
||||
**Important:**
|
||||
- Item-level coupon (not transaction-level)
|
||||
- Multiple items can have different coupons
|
||||
- Usually paired with `discount` field
|
||||
|
||||
```javascript
|
||||
'coupon': 'SUMMER20'
|
||||
```
|
||||
|
||||
**Transaction-Level Example:**
|
||||
```javascript
|
||||
gtag('event', 'purchase', {
|
||||
'transaction_id': 'TXN_12345',
|
||||
'coupon': 'SITEWIDE10', // Applies to whole purchase
|
||||
'items': [
|
||||
{
|
||||
'item_id': 'SKU_001',
|
||||
'coupon': 'PRODUCT15' // Different coupon on this item
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### discount (OPTIONAL)
|
||||
|
||||
**Purpose:** Discount amount on item
|
||||
|
||||
**Format:** Number (decimal, discount amount in transaction currency)
|
||||
|
||||
**Examples:**
|
||||
- `10.00` - $10 discount
|
||||
- `5.50` - $5.50 discount
|
||||
- `0.99` - 99 cents discount
|
||||
|
||||
**Relationship to Price:**
|
||||
```
|
||||
original_price: 99.99
|
||||
discount: 10.00
|
||||
final_price: 89.99
|
||||
```
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
'price': 99.99,
|
||||
'discount': 10.00,
|
||||
// Customer pays: 99.99 - 10.00 = 89.99
|
||||
```
|
||||
|
||||
**Reporting Use:**
|
||||
- Discount impact analysis
|
||||
- Discount effectiveness
|
||||
- Revenue impact of promotions
|
||||
|
||||
---
|
||||
|
||||
### affiliation (OPTIONAL)
|
||||
|
||||
**Purpose:** Vendor/store name for multi-vendor platforms
|
||||
|
||||
**Format:** String
|
||||
|
||||
**Examples:**
|
||||
- `Nike Store`
|
||||
- `Amazon Marketplace`
|
||||
- `Vendor ABC`
|
||||
- `Warehouse Location 3`
|
||||
|
||||
**Use Cases:**
|
||||
- Multi-vendor marketplaces
|
||||
- Multiple physical locations
|
||||
- Different store names
|
||||
|
||||
```javascript
|
||||
'affiliation': 'Nike Store'
|
||||
```
|
||||
|
||||
**Transaction-Level:**
|
||||
```javascript
|
||||
gtag('event', 'purchase', {
|
||||
'affiliation': 'Main Online Store', // Default/transaction-level
|
||||
'items': [
|
||||
{
|
||||
'item_id': 'SKU_001',
|
||||
'affiliation': 'Nike Store' // Override for this item
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### item_list_id (OPTIONAL)
|
||||
|
||||
**Purpose:** Identifier for the list/collection item came from
|
||||
|
||||
**Format:** String (identifier, not display name)
|
||||
|
||||
**Examples:**
|
||||
- `search_results`
|
||||
- `category_electronics`
|
||||
- `homepage_featured`
|
||||
- `related_products`
|
||||
- `sale_section`
|
||||
|
||||
**Use Cases:**
|
||||
```javascript
|
||||
// From search results
|
||||
gtag('event', 'select_item', {
|
||||
'items': [{
|
||||
'item_id': 'SKU_123',
|
||||
'item_list_id': 'search_results'
|
||||
}]
|
||||
});
|
||||
|
||||
// From category
|
||||
gtag('event', 'view_item', {
|
||||
'items': [{
|
||||
'item_id': 'SKU_123',
|
||||
'item_list_id': 'category_shoes'
|
||||
}]
|
||||
});
|
||||
|
||||
// From recommendations
|
||||
gtag('event', 'select_item', {
|
||||
'items': [{
|
||||
'item_id': 'SKU_123',
|
||||
'item_list_id': 'recommendations_widget'
|
||||
}]
|
||||
});
|
||||
```
|
||||
|
||||
**Reporting Use:**
|
||||
- Track which collections drive sales
|
||||
- Compare performance of different lists
|
||||
- Identify high-converting collections
|
||||
|
||||
---
|
||||
|
||||
### item_list_name (OPTIONAL)
|
||||
|
||||
**Purpose:** Display name for the list/collection
|
||||
|
||||
**Format:** String (human-readable)
|
||||
|
||||
**Examples:**
|
||||
- `Search Results for Shoes`
|
||||
- `Electronics Category`
|
||||
- `New Arrivals`
|
||||
- `Customers Also Bought`
|
||||
- `Summer Sale`
|
||||
|
||||
**Important:**
|
||||
- Use display name (what users see)
|
||||
- Pair with `item_list_id` for consistency
|
||||
- Should be understandable in reports
|
||||
|
||||
```javascript
|
||||
'item_list_name': 'New Arrivals'
|
||||
```
|
||||
|
||||
**Full Example:**
|
||||
```javascript
|
||||
gtag('event', 'view_item_list', {
|
||||
'items': [{...}],
|
||||
'item_list_id': 'featured_section',
|
||||
'item_list_name': 'Featured Products - Home Page'
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### location_id (OPTIONAL)
|
||||
|
||||
**Purpose:** Physical store location identifier
|
||||
|
||||
**Format:** String (store ID or location code)
|
||||
|
||||
**Examples:**
|
||||
- `store_123`
|
||||
- `NYC_Broadway`
|
||||
- `location_LAX_001`
|
||||
- `warehouse_sf`
|
||||
|
||||
**Use Cases:**
|
||||
- Multi-location retailers
|
||||
- In-store purchases
|
||||
- Store-based pickup
|
||||
- Inventory tracking
|
||||
|
||||
```javascript
|
||||
'location_id': 'store_downtown_la'
|
||||
```
|
||||
|
||||
**E-Commerce + In-Store:**
|
||||
```javascript
|
||||
gtag('event', 'purchase', {
|
||||
'items': [
|
||||
{
|
||||
'item_id': 'SKU_001',
|
||||
'location_id': 'store_sf' // Picked up at SF store
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### index (OPTIONAL)
|
||||
|
||||
**Purpose:** Position of item in list (0-based)
|
||||
|
||||
**Format:** Integer (0, 1, 2, ...)
|
||||
|
||||
**Important:**
|
||||
- 0-based indexing (first item = 0)
|
||||
- Useful for tracking list position impact
|
||||
- Typically auto-generated
|
||||
|
||||
```javascript
|
||||
'items': [
|
||||
{
|
||||
'item_id': 'SKU_001',
|
||||
'item_name': 'First Product',
|
||||
'index': 0
|
||||
},
|
||||
{
|
||||
'item_id': 'SKU_002',
|
||||
'item_name': 'Second Product',
|
||||
'index': 1
|
||||
},
|
||||
{
|
||||
'item_id': 'SKU_003',
|
||||
'item_name': 'Third Product',
|
||||
'index': 2
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
**Reporting Use:**
|
||||
- Position analysis (first item gets more clicks?)
|
||||
- List effectiveness by position
|
||||
- A/B test different orderings
|
||||
|
||||
---
|
||||
|
||||
## Custom Item Parameters
|
||||
|
||||
**Advanced:** Register custom item parameters as custom dimensions
|
||||
|
||||
**Example Custom Parameters:**
|
||||
```javascript
|
||||
'items': [{
|
||||
'item_id': 'SKU_001',
|
||||
'item_name': 'Product A',
|
||||
|
||||
// Custom parameters (must be registered as custom dimensions)
|
||||
'item_color': 'blue',
|
||||
'item_material': 'cotton',
|
||||
'supplier': 'vendor_123',
|
||||
'profit_margin': '45%',
|
||||
'in_stock': true
|
||||
}]
|
||||
```
|
||||
|
||||
**Registration Process:**
|
||||
1. Send custom parameter in items array
|
||||
2. Admin → Custom Definitions → Create Custom Dimension
|
||||
3. Set Scope: "Item"
|
||||
4. Map to parameter name (e.g., "item_color")
|
||||
5. Wait 24-48 hours
|
||||
6. Use in "Items" report
|
||||
|
||||
---
|
||||
|
||||
## Complete Examples
|
||||
|
||||
### Simple Product
|
||||
|
||||
```javascript
|
||||
'items': [{
|
||||
'item_id': 'TSHIRT_001',
|
||||
'item_name': 'Blue T-Shirt',
|
||||
'price': 29.99,
|
||||
'quantity': 1,
|
||||
'item_category': 'Apparel'
|
||||
}]
|
||||
```
|
||||
|
||||
### Product with Variants
|
||||
|
||||
```javascript
|
||||
'items': [{
|
||||
'item_id': 'PHONE_IPHONE_BLACK_256GB',
|
||||
'item_name': 'iPhone 15 Pro - Black - 256GB',
|
||||
'item_brand': 'Apple',
|
||||
'item_category': 'Electronics',
|
||||
'item_category2': 'Phones',
|
||||
'item_category3': 'Smartphones',
|
||||
'item_variant': 'Black/256GB',
|
||||
'price': 999.99,
|
||||
'quantity': 1
|
||||
}]
|
||||
```
|
||||
|
||||
### Multiple Items with Discounts
|
||||
|
||||
```javascript
|
||||
'items': [
|
||||
{
|
||||
'item_id': 'SKU_001',
|
||||
'item_name': 'Product A',
|
||||
'price': 99.99,
|
||||
'quantity': 2,
|
||||
'item_category': 'Electronics',
|
||||
'coupon': 'SUMMER20',
|
||||
'discount': 20.00
|
||||
},
|
||||
{
|
||||
'item_id': 'SKU_002',
|
||||
'item_name': 'Product B',
|
||||
'price': 50.00,
|
||||
'quantity': 1,
|
||||
'item_category': 'Accessories',
|
||||
'discount': 5.00
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Marketplace with Affiliations
|
||||
|
||||
```javascript
|
||||
'items': [
|
||||
{
|
||||
'item_id': 'VENDOR1_SKU_001',
|
||||
'item_name': 'Product from Vendor 1',
|
||||
'affiliation': 'Vendor ABC',
|
||||
'price': 49.99,
|
||||
'quantity': 1
|
||||
},
|
||||
{
|
||||
'item_id': 'VENDOR2_SKU_002',
|
||||
'item_name': 'Product from Vendor 2',
|
||||
'affiliation': 'Vendor XYZ',
|
||||
'price': 29.99,
|
||||
'quantity': 1
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Validation Rules
|
||||
|
||||
**Requirements:**
|
||||
- ✅ At least one item in array (minimum 1)
|
||||
- ✅ Maximum 27 items per event
|
||||
- ✅ Each item has item_id OR item_name (at least one)
|
||||
- ✅ price and quantity are numbers (not strings)
|
||||
- ✅ quantity ≥ 1
|
||||
- ✅ price > 0 (positive value)
|
||||
|
||||
**Common Errors:**
|
||||
- ❌ Empty items array `[]`
|
||||
- ❌ Item without ID or name
|
||||
- ❌ Price as string `"99.99"` (must be number `99.99`)
|
||||
- ❌ Quantity as string `"2"` (must be number `2`)
|
||||
- ❌ Negative price or quantity
|
||||
- ❌ More than 27 items
|
||||
|
||||
---
|
||||
|
||||
## Testing Items Array
|
||||
|
||||
**Use DebugView to verify:**
|
||||
|
||||
1. Event contains items array
|
||||
2. Each item has at least item_id or item_name
|
||||
3. Prices and quantities are numeric
|
||||
4. Array structure is valid JSON
|
||||
5. No special characters in field names
|
||||
|
||||
**Debug Checklist:**
|
||||
```
|
||||
✓ Items array present
|
||||
✓ Minimum 1 item
|
||||
✓ Maximum 27 items
|
||||
✓ Item ID or name exists
|
||||
✓ Numeric values (not strings)
|
||||
✓ Prices match product catalog
|
||||
✓ Quantities match cart data
|
||||
✓ Categories consistent with product data
|
||||
```
|
||||
@@ -0,0 +1,553 @@
|
||||
# Complete Recommended Events Catalog
|
||||
|
||||
## All Recommended Events Reference
|
||||
|
||||
This is the complete catalog of all Google-recommended event names with required and optional parameters.
|
||||
|
||||
---
|
||||
|
||||
## ENGAGEMENT EVENTS
|
||||
|
||||
### login
|
||||
|
||||
**Purpose:** User successfully authenticates
|
||||
|
||||
**Parameters:**
|
||||
- `method` (required) - Authentication method used
|
||||
- Values: email, phone, social, google, facebook, etc.
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'login', {
|
||||
'method': 'google'
|
||||
});
|
||||
```
|
||||
|
||||
**Use Cases:**
|
||||
- User logs in with email/password
|
||||
- User authenticates with social provider
|
||||
- Two-factor authentication completed
|
||||
|
||||
---
|
||||
|
||||
### sign_up
|
||||
|
||||
**Purpose:** New user account created
|
||||
|
||||
**Parameters:**
|
||||
- `method` (required) - Registration method
|
||||
- Values: email, social, phone, etc.
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'sign_up', {
|
||||
'method': 'email'
|
||||
});
|
||||
```
|
||||
|
||||
**Use Cases:**
|
||||
- User completes registration form
|
||||
- User creates account via social provider
|
||||
- App installs and creates account
|
||||
|
||||
---
|
||||
|
||||
### view_item
|
||||
|
||||
**Purpose:** User views product detail page
|
||||
|
||||
**Parameters:**
|
||||
- `items` (required) - Array of product objects with item_id and item_name
|
||||
- `value` (recommended) - Total item price
|
||||
- `currency` (recommended) - Currency code (USD, EUR, GBP)
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'view_item', {
|
||||
'items': [{
|
||||
'item_id': 'SKU_123',
|
||||
'item_name': 'Product Name',
|
||||
'item_category': 'Electronics',
|
||||
'price': 99.99
|
||||
}],
|
||||
'value': 99.99,
|
||||
'currency': 'USD'
|
||||
});
|
||||
```
|
||||
|
||||
**Reporting Impact:**
|
||||
- Enables "Items" report
|
||||
- Feeds conversion modeling
|
||||
- Product-level analysis
|
||||
|
||||
---
|
||||
|
||||
### view_item_list
|
||||
|
||||
**Purpose:** User views product list/search results
|
||||
|
||||
**Parameters:**
|
||||
- `items` (required) - Array of products
|
||||
- `item_list_id` (optional) - List identifier (e.g., "search_results")
|
||||
- `item_list_name` (optional) - List name (e.g., "Search Results for Shoes")
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'view_item_list', {
|
||||
'items': [
|
||||
{
|
||||
'item_id': 'SKU_001',
|
||||
'item_name': 'Product A',
|
||||
'item_category': 'Shoes'
|
||||
},
|
||||
{
|
||||
'item_id': 'SKU_002',
|
||||
'item_name': 'Product B',
|
||||
'item_category': 'Shoes'
|
||||
}
|
||||
],
|
||||
'item_list_name': 'Search Results'
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### select_item
|
||||
|
||||
**Purpose:** User selects item from list
|
||||
|
||||
**Parameters:**
|
||||
- `items` (required) - Selected item(s)
|
||||
- `item_list_id` (optional) - List identifier
|
||||
- `item_list_name` (optional) - List name
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'select_item', {
|
||||
'items': [{
|
||||
'item_id': 'SKU_123',
|
||||
'item_name': 'Selected Product',
|
||||
'item_list_name': 'Related Products'
|
||||
}]
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### search
|
||||
|
||||
**Purpose:** User performs site search
|
||||
|
||||
**Parameters:**
|
||||
- `search_term` (required) - What user searched for
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'search', {
|
||||
'search_term': 'blue shoes'
|
||||
});
|
||||
```
|
||||
|
||||
**Reporting Impact:**
|
||||
- Search terms report
|
||||
- Search-to-purchase analysis
|
||||
|
||||
---
|
||||
|
||||
### view_promotion
|
||||
|
||||
**Purpose:** Promotional banner/offer displayed to user
|
||||
|
||||
**Parameters:**
|
||||
- `promotion_id` (recommended) - Promotion identifier
|
||||
- `promotion_name` (recommended) - Promotion display name
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'view_promotion', {
|
||||
'promotion_id': 'PROMO_2024_SUMMER',
|
||||
'promotion_name': 'Summer Sale - 50% Off'
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### select_promotion
|
||||
|
||||
**Purpose:** User clicks/selects promotion
|
||||
|
||||
**Parameters:**
|
||||
- `promotion_id` (recommended) - Promotion identifier
|
||||
- `promotion_name` (recommended) - Promotion name
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'select_promotion', {
|
||||
'promotion_id': 'PROMO_2024_SUMMER',
|
||||
'promotion_name': 'Summer Sale - 50% Off'
|
||||
});
|
||||
```
|
||||
|
||||
**Reporting Impact:**
|
||||
- Promotion performance
|
||||
- Promotion-to-purchase funnel
|
||||
|
||||
---
|
||||
|
||||
## MONETIZATION EVENTS (ECOMMERCE)
|
||||
|
||||
### add_to_cart
|
||||
|
||||
**Purpose:** Item added to shopping cart
|
||||
|
||||
**Parameters:**
|
||||
- `items` (required) - Product(s) added
|
||||
- `value` (recommended) - Total value of items
|
||||
- `currency` (recommended) - Currency code
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'add_to_cart', {
|
||||
'items': [{
|
||||
'item_id': 'SKU_123',
|
||||
'item_name': 'Product Name',
|
||||
'price': 99.99,
|
||||
'quantity': 1
|
||||
}],
|
||||
'value': 99.99,
|
||||
'currency': 'USD'
|
||||
});
|
||||
```
|
||||
|
||||
**Reporting Impact:**
|
||||
- Cart funnel analysis
|
||||
- Add-to-cart rate metrics
|
||||
|
||||
---
|
||||
|
||||
### remove_from_cart
|
||||
|
||||
**Purpose:** Item removed from cart
|
||||
|
||||
**Parameters:**
|
||||
- `items` (required) - Product(s) removed
|
||||
- `value` (recommended) - Total value of removed items
|
||||
- `currency` (recommended) - Currency code
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'remove_from_cart', {
|
||||
'items': [{
|
||||
'item_id': 'SKU_123',
|
||||
'price': 99.99
|
||||
}],
|
||||
'value': 99.99,
|
||||
'currency': 'USD'
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### view_cart
|
||||
|
||||
**Purpose:** User views shopping cart
|
||||
|
||||
**Parameters:**
|
||||
- `items` (required) - Items in cart
|
||||
- `value` (recommended) - Total cart value
|
||||
- `currency` (recommended) - Currency code
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'view_cart', {
|
||||
'items': [{...}, {...}],
|
||||
'value': 299.98,
|
||||
'currency': 'USD'
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### begin_checkout
|
||||
|
||||
**Purpose:** User starts checkout process (CRITICAL EVENT)
|
||||
|
||||
**Parameters:**
|
||||
- `items` (required) - Products being purchased
|
||||
- `value` (required) - Total checkout value
|
||||
- `currency` (required) - Currency code
|
||||
- `coupon` (optional) - Discount code applied
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'begin_checkout', {
|
||||
'items': [{...}, {...}],
|
||||
'value': 329.98,
|
||||
'currency': 'USD',
|
||||
'coupon': 'SUMMER20'
|
||||
});
|
||||
```
|
||||
|
||||
**Reporting Impact:**
|
||||
- Most important funnel metric
|
||||
- Checkout abandonment analysis
|
||||
- Conversion modeling baseline
|
||||
|
||||
---
|
||||
|
||||
### add_shipping_info
|
||||
|
||||
**Purpose:** User selects shipping method
|
||||
|
||||
**Parameters:**
|
||||
- `items` (required) - Products being shipped
|
||||
- `shipping_tier` (recommended) - Shipping option selected
|
||||
- Values: standard, express, overnight, pickup, etc.
|
||||
- `value` (recommended) - Total value
|
||||
- `currency` (recommended) - Currency code
|
||||
- `coupon` (optional) - Applied coupon
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'add_shipping_info', {
|
||||
'items': [{...}, {...}],
|
||||
'shipping_tier': 'express',
|
||||
'value': 329.98,
|
||||
'currency': 'USD'
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### add_payment_info
|
||||
|
||||
**Purpose:** User enters payment information
|
||||
|
||||
**Parameters:**
|
||||
- `payment_type` (recommended) - Payment method
|
||||
- Values: credit_card, debit_card, paypal, apple_pay, google_pay, etc.
|
||||
- `items` (optional) - Products being paid for
|
||||
- `value` (optional) - Total value
|
||||
- `currency` (optional) - Currency code
|
||||
- `coupon` (optional) - Applied coupon
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'add_payment_info', {
|
||||
'payment_type': 'credit_card',
|
||||
'items': [{...}, {...}],
|
||||
'value': 329.98,
|
||||
'currency': 'USD'
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### purchase
|
||||
|
||||
**Purpose:** Purchase/transaction completed (MOST IMPORTANT EVENT)
|
||||
|
||||
**Parameters:**
|
||||
- `transaction_id` (required) - Unique transaction identifier
|
||||
- `value` (recommended) - Total transaction value
|
||||
- `currency` (recommended) - Currency code (ISO 4217)
|
||||
- `tax` (optional) - Tax amount
|
||||
- `shipping` (optional) - Shipping cost
|
||||
- `coupon` (optional) - Discount code
|
||||
- `affiliation` (optional) - Store/vendor name
|
||||
- `items` (recommended) - Products purchased
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'purchase', {
|
||||
'transaction_id': 'TXN_12345678',
|
||||
'affiliation': 'Online Store',
|
||||
'value': 329.98,
|
||||
'currency': 'USD',
|
||||
'tax': 24.99,
|
||||
'shipping': 15.00,
|
||||
'coupon': 'SUMMER20',
|
||||
'items': [{
|
||||
'item_id': 'SKU_123',
|
||||
'item_name': 'Product A',
|
||||
'price': 99.99,
|
||||
'quantity': 2,
|
||||
'item_category': 'Electronics'
|
||||
}, {
|
||||
'item_id': 'SKU_124',
|
||||
'item_name': 'Product B',
|
||||
'price': 130.00,
|
||||
'quantity': 1
|
||||
}]
|
||||
});
|
||||
```
|
||||
|
||||
**Critical Rules:**
|
||||
- `transaction_id` MUST be unique per purchase
|
||||
- MUST NOT be reused across different transactions
|
||||
- MUST be consistent across all touchpoints (GTM, backend, etc.)
|
||||
|
||||
**Reporting Impact:**
|
||||
- Revenue tracking
|
||||
- Ecommerce conversion reports
|
||||
- Attribution modeling
|
||||
- Google Ads conversion tracking
|
||||
- GA4 Key Event (marked by default)
|
||||
|
||||
---
|
||||
|
||||
### refund
|
||||
|
||||
**Purpose:** Purchase refund processed
|
||||
|
||||
**Parameters:**
|
||||
- `transaction_id` (required) - Original transaction ID
|
||||
- `value` (required) - Refund amount
|
||||
- `currency` (required) - Currency code
|
||||
- `items` (optional) - Refunded products
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'refund', {
|
||||
'transaction_id': 'TXN_12345678',
|
||||
'value': 99.99,
|
||||
'currency': 'USD',
|
||||
'items': [{
|
||||
'item_id': 'SKU_123',
|
||||
'quantity': 1
|
||||
}]
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### add_to_wishlist
|
||||
|
||||
**Purpose:** Item added to wishlist
|
||||
|
||||
**Parameters:**
|
||||
- `items` (required) - Product(s) wishlisted
|
||||
- `value` (optional) - Total value
|
||||
- `currency` (optional) - Currency code
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'add_to_wishlist', {
|
||||
'items': [{
|
||||
'item_id': 'SKU_123',
|
||||
'item_name': 'Product Name',
|
||||
'price': 99.99
|
||||
}],
|
||||
'value': 99.99,
|
||||
'currency': 'USD'
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## OTHER RECOMMENDED EVENTS
|
||||
|
||||
### generate_lead
|
||||
|
||||
**Purpose:** Lead generated (form submission, demo request, etc.)
|
||||
|
||||
**Parameters:**
|
||||
- `value` (optional) - Lead value estimate
|
||||
- `currency` (optional) - Currency code
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'generate_lead', {
|
||||
'value': 50.00,
|
||||
'currency': 'USD'
|
||||
});
|
||||
```
|
||||
|
||||
**Use Cases:**
|
||||
- Contact form submission
|
||||
- Demo request
|
||||
- Free trial signup
|
||||
- Newsletter subscription
|
||||
|
||||
---
|
||||
|
||||
### select_content
|
||||
|
||||
**Purpose:** User selects content
|
||||
|
||||
**Parameters:**
|
||||
- `content_type` (optional) - Type of content (video, article, product, etc.)
|
||||
- `item_id` (optional) - Content identifier
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'select_content', {
|
||||
'content_type': 'video',
|
||||
'item_id': 'video_123'
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### share
|
||||
|
||||
**Purpose:** Content shared
|
||||
|
||||
**Parameters:**
|
||||
- `method` (optional) - Share method (email, social, link, etc.)
|
||||
- `content_type` (optional) - Type of content shared
|
||||
- `item_id` (optional) - Content identifier
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'share', {
|
||||
'method': 'email',
|
||||
'content_type': 'article',
|
||||
'item_id': 'article_456'
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### join_group
|
||||
|
||||
**Purpose:** User joins group/team
|
||||
|
||||
**Parameters:**
|
||||
- `group_id` (optional) - Group identifier
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
gtag('event', 'join_group', {
|
||||
'group_id': 'team_123'
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Event Parameter Limits
|
||||
|
||||
**Global Limits (All Events):**
|
||||
- Maximum 25 parameters per event
|
||||
- Parameter name: 40 characters max
|
||||
- Parameter value: 100 characters max
|
||||
- Exceptions:
|
||||
- page_title: 300 characters
|
||||
- page_referrer: 420 characters
|
||||
- page_location: 1000 characters
|
||||
|
||||
**Items Array Limits:**
|
||||
- Maximum 27 items per event
|
||||
- Each item: up to 25 parameters
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Consistency:** Use exact recommended event names (case-sensitive, lowercase)
|
||||
2. **Parameter Coverage:** Include all "recommended" parameters when applicable
|
||||
3. **Currency:** Always include currency for monetary events (USD, EUR, GBP, etc.)
|
||||
4. **Transaction ID:** Generate unique, non-reusable transaction IDs for purchases
|
||||
5. **Testing:** Verify events in DebugView before production launch
|
||||
6. **Items Array:** Always include item_id OR item_name (at least one required)
|
||||
7. **Value Accuracy:** Ensure value parameters match actual transaction amounts
|
||||
Reference in New Issue
Block a user