Initial commit
This commit is contained in:
380
skills/ga4-gtm-integration/references/gtm-best-practices-ga4.md
Normal file
380
skills/ga4-gtm-integration/references/gtm-best-practices-ga4.md
Normal file
@@ -0,0 +1,380 @@
|
||||
# GTM Best Practices for GA4 Implementation
|
||||
|
||||
## Container Organization
|
||||
|
||||
### Naming Conventions
|
||||
|
||||
**Tags:**
|
||||
- `GA4 - Configuration` (base tag)
|
||||
- `GA4 - [Event Name] - [Description]`
|
||||
- Examples:
|
||||
- `GA4 - Button Click - Subscribe`
|
||||
- `GA4 - Form Submit - Contact`
|
||||
- `GA4 - Purchase`
|
||||
|
||||
**Triggers:**
|
||||
- `[Type] - [Description]`
|
||||
- Examples:
|
||||
- `All Pages`
|
||||
- `Click - Subscribe Button`
|
||||
- `Form - Contact Submit`
|
||||
- `Custom Event - add_to_cart`
|
||||
|
||||
**Variables:**
|
||||
- `DL - [Name]` for Data Layer Variables
|
||||
- `JS - [Name]` for JavaScript Variables
|
||||
- `Cookie - [Name]` for Cookies
|
||||
- Examples:
|
||||
- `DL - Product ID`
|
||||
- `JS - User Tier`
|
||||
- `Cookie - Session ID`
|
||||
|
||||
### Folder Structure
|
||||
|
||||
**Organize by Function:**
|
||||
```
|
||||
Folders:
|
||||
├── GA4 - Core (Configuration tag)
|
||||
├── GA4 - E-commerce (Purchase, add_to_cart, etc.)
|
||||
├── GA4 - Engagement (Scroll, clicks, video)
|
||||
├── GA4 - Forms
|
||||
└── Variables - Data Layer
|
||||
```
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### Rule 1: Use One GA4 Configuration Tag
|
||||
|
||||
**CORRECT:**
|
||||
- One GA4 Configuration tag
|
||||
- Fires on Initialization - All Pages
|
||||
- Multiple event tags reference same Measurement ID
|
||||
|
||||
**WRONG:**
|
||||
- Multiple GA4 Configuration tags
|
||||
- Different Measurement IDs in same container
|
||||
|
||||
### Rule 2: Minimize Data Layer Pushes
|
||||
|
||||
**CORRECT:**
|
||||
```javascript
|
||||
dataLayer.push({
|
||||
'event': 'add_to_cart',
|
||||
'product_id': 'SKU_123',
|
||||
'product_name': 'Blue T-Shirt',
|
||||
'price': 29.99
|
||||
});
|
||||
```
|
||||
|
||||
**WRONG:**
|
||||
```javascript
|
||||
dataLayer.push({'event': 'add_to_cart'});
|
||||
dataLayer.push({'product_id': 'SKU_123'});
|
||||
dataLayer.push({'product_name': 'Blue T-Shirt'});
|
||||
dataLayer.push({'price': 29.99});
|
||||
```
|
||||
|
||||
### Rule 3: Use Specific Triggers
|
||||
|
||||
**CORRECT:**
|
||||
```
|
||||
Trigger Type: Click - All Elements
|
||||
Fires on: Some Clicks
|
||||
Condition: Click ID equals subscribe-btn
|
||||
```
|
||||
|
||||
**WRONG:**
|
||||
```
|
||||
Trigger Type: Click - All Elements
|
||||
Fires on: All Clicks
|
||||
(Then filter in tag)
|
||||
```
|
||||
|
||||
### Rule 4: Batch Event Parameters
|
||||
|
||||
**CORRECT:**
|
||||
- Add all parameters in single event tag
|
||||
- Use data layer variables efficiently
|
||||
|
||||
**WRONG:**
|
||||
- Multiple tags for same event
|
||||
- Separate pushes for each parameter
|
||||
|
||||
## Data Quality
|
||||
|
||||
### Use Consistent Event Names
|
||||
|
||||
**Best Practice:**
|
||||
- Follow GA4 recommended event names
|
||||
- Use snake_case consistently
|
||||
- Document custom events
|
||||
|
||||
**Recommended Events:**
|
||||
- `purchase`, `add_to_cart`, `begin_checkout`
|
||||
- `sign_up`, `login`, `generate_lead`
|
||||
- `view_item`, `view_item_list`, `select_item`
|
||||
|
||||
**Custom Events:**
|
||||
- `button_click`, `form_submit`, `video_start`
|
||||
- Keep lowercase with underscores
|
||||
- Limit to 40 characters
|
||||
|
||||
### Validate Data Types
|
||||
|
||||
**Correct Types:**
|
||||
- **String:** Event names, IDs, categories
|
||||
- **Number:** Values, prices, quantities, revenue
|
||||
- **Boolean:** true/false (not "true"/"false")
|
||||
- **Array:** Items array for e-commerce
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
dataLayer.push({
|
||||
'event': 'purchase',
|
||||
'transaction_id': 'T_12345', // String
|
||||
'value': 99.99, // Number
|
||||
'currency': 'USD', // String
|
||||
'items': [...] // Array
|
||||
});
|
||||
```
|
||||
|
||||
### Avoid PII (Personally Identifiable Information)
|
||||
|
||||
**DO NOT Track:**
|
||||
- Email addresses
|
||||
- Phone numbers
|
||||
- Full names
|
||||
- Street addresses
|
||||
- Social Security numbers
|
||||
|
||||
**Safe to Track:**
|
||||
- Email domain (`@gmail.com`, `@company.com`)
|
||||
- User IDs (hashed/anonymized)
|
||||
- City/region (not specific addresses)
|
||||
|
||||
## Testing and QA
|
||||
|
||||
### Pre-Publication Checklist
|
||||
|
||||
- [ ] All tags fire in Preview mode
|
||||
- [ ] Variables populate correctly
|
||||
- [ ] Event names follow naming conventions
|
||||
- [ ] Parameters have correct data types
|
||||
- [ ] No PII in parameters
|
||||
- [ ] Events appear in GA4 DebugView
|
||||
- [ ] No duplicate events
|
||||
- [ ] Data layer formatted correctly
|
||||
- [ ] Documentation updated
|
||||
- [ ] Version description written
|
||||
|
||||
### Version Control
|
||||
|
||||
**Every Publish:**
|
||||
1. **Version Name:** Descriptive (e.g., "GA4 E-commerce Tracking - Nov 2024")
|
||||
2. **Version Description:** Detailed list of changes
|
||||
3. **Workspace Name:** Feature/task description
|
||||
|
||||
**Example Version Description:**
|
||||
```
|
||||
Changes:
|
||||
- Added GA4 purchase event tracking
|
||||
- Created data layer variables for transaction data
|
||||
- Added form submission tracking for contact form
|
||||
- Fixed duplicate page_view issue
|
||||
|
||||
Tested:
|
||||
- Purchase flow (3 test transactions)
|
||||
- Contact form submission
|
||||
- All pages for duplicate events
|
||||
```
|
||||
|
||||
### Rollback Plan
|
||||
|
||||
**If Issues After Publishing:**
|
||||
1. Go to **Versions** tab
|
||||
2. Find previous working version
|
||||
3. Click **"•••"** → **Publish**
|
||||
4. Confirm rollback
|
||||
|
||||
**Prevention:**
|
||||
- Test thoroughly before publishing
|
||||
- Publish during low-traffic periods
|
||||
- Monitor for 30+ minutes after publishing
|
||||
|
||||
## Security and Privacy
|
||||
|
||||
### Use Appropriate Consent Mode
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
// Set default consent state
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
|
||||
gtag('consent', 'default', {
|
||||
'ad_storage': 'denied',
|
||||
'analytics_storage': 'denied'
|
||||
});
|
||||
|
||||
// Update after user consent
|
||||
gtag('consent', 'update', {
|
||||
'ad_storage': 'granted',
|
||||
'analytics_storage': 'granted'
|
||||
});
|
||||
```
|
||||
|
||||
### IP Anonymization
|
||||
|
||||
**Not Needed for GA4:**
|
||||
- GA4 does not log or store IP addresses by default
|
||||
- No `anonymize_ip` parameter needed
|
||||
|
||||
### Data Retention Settings
|
||||
|
||||
**In GA4:**
|
||||
1. Admin → Data Settings → Data Retention
|
||||
2. Set event data retention (2 or 14 months)
|
||||
3. Enable/disable "Reset user data on new activity"
|
||||
|
||||
## Maintenance
|
||||
|
||||
### Regular Audits
|
||||
|
||||
**Monthly:**
|
||||
- Review Tags Not Fired section
|
||||
- Check for broken triggers
|
||||
- Verify variables still working
|
||||
- Test critical paths
|
||||
|
||||
**Quarterly:**
|
||||
- Full container audit
|
||||
- Remove unused tags/triggers/variables
|
||||
- Update documentation
|
||||
- Review naming conventions
|
||||
|
||||
**Annually:**
|
||||
- Major cleanup
|
||||
- Archive old tags
|
||||
- Update to latest GA4 features
|
||||
|
||||
### Documentation
|
||||
|
||||
**Maintain Documentation For:**
|
||||
- All custom events and parameters
|
||||
- Data layer structure
|
||||
- Trigger logic
|
||||
- Variable mappings
|
||||
- Change history
|
||||
|
||||
**Example Documentation:**
|
||||
```markdown
|
||||
# Custom Events
|
||||
|
||||
## add_to_cart
|
||||
Fires when: User clicks "Add to Cart" button
|
||||
Parameters:
|
||||
- product_id (string): SKU
|
||||
- product_name (string): Product name
|
||||
- price (number): Unit price
|
||||
- quantity (number): Quantity added
|
||||
Data Layer: dataLayer.push({event: 'add_to_cart', ...})
|
||||
GTM Tag: GA4 - Add to Cart
|
||||
Trigger: Custom Event - add_to_cart
|
||||
```
|
||||
|
||||
## Common Pitfalls to Avoid
|
||||
|
||||
### Pitfall 1: Multiple Measurement IDs
|
||||
|
||||
**Issue:** Using different Measurement IDs in event tags
|
||||
**Solution:** Use same Measurement ID across all GA4 tags
|
||||
|
||||
### Pitfall 2: Not Clearing ecommerce Object
|
||||
|
||||
**Issue:** Old ecommerce data persists across events
|
||||
**Solution:** Clear before each ecommerce push
|
||||
```javascript
|
||||
dataLayer.push({ ecommerce: null });
|
||||
dataLayer.push({ event: 'purchase', ecommerce: {...} });
|
||||
```
|
||||
|
||||
### Pitfall 3: Tracking PII
|
||||
|
||||
**Issue:** Accidentally sending email addresses or names
|
||||
**Solution:** Review all data layer pushes and parameters
|
||||
|
||||
### Pitfall 4: Inconsistent Event Names
|
||||
|
||||
**Issue:** `buttonClick`, `button_click`, `Button_Click`
|
||||
**Solution:** Use lowercase with underscores consistently
|
||||
|
||||
### Pitfall 5: Publishing Without Testing
|
||||
|
||||
**Issue:** Broken tags go live
|
||||
**Solution:** Always use Preview mode before publishing
|
||||
|
||||
### Pitfall 6: No Version Descriptions
|
||||
|
||||
**Issue:** Can't identify what changed in version history
|
||||
**Solution:** Write detailed version descriptions
|
||||
|
||||
### Pitfall 7: Overcomplicating Setup
|
||||
|
||||
**Issue:** Too many tags for simple tracking
|
||||
**Solution:** Start simple, add complexity as needed
|
||||
|
||||
## Migration from gtag.js to GTM
|
||||
|
||||
**Steps:**
|
||||
|
||||
1. **Remove gtag.js snippet** from website
|
||||
2. **Install GTM container** code
|
||||
3. **Create GA4 Configuration tag** in GTM
|
||||
4. **Migrate custom events** to GTM event tags
|
||||
5. **Test thoroughly** in Preview mode
|
||||
6. **Publish** GTM container
|
||||
|
||||
**Benefits:**
|
||||
- No code changes needed for new tracking
|
||||
- Easier testing with Preview mode
|
||||
- Centralized tag management
|
||||
- Better collaboration
|
||||
|
||||
## Collaboration Best Practices
|
||||
|
||||
### Workspaces
|
||||
|
||||
**Use Workspaces For:**
|
||||
- Feature development
|
||||
- Testing major changes
|
||||
- Team collaboration
|
||||
|
||||
**Best Practices:**
|
||||
- One workspace per feature/task
|
||||
- Descriptive workspace names
|
||||
- Merge/publish when complete
|
||||
|
||||
### User Permissions
|
||||
|
||||
**Roles:**
|
||||
- **No Access:** No access to container
|
||||
- **Read:** View-only access
|
||||
- **Edit:** Create/modify tags (can't publish)
|
||||
- **Approve:** Publish changes
|
||||
- **Publish:** Full control
|
||||
|
||||
**Best Practice:**
|
||||
- Limit Publish access
|
||||
- Most users: Edit access
|
||||
- Senior team: Approve/Publish
|
||||
|
||||
### Change Management
|
||||
|
||||
**Process:**
|
||||
1. Create workspace for change
|
||||
2. Implement and test
|
||||
3. Submit for review (if applicable)
|
||||
4. Peer review changes
|
||||
5. Final testing in Preview
|
||||
6. Publish with detailed description
|
||||
7. Monitor for 30+ minutes
|
||||
Reference in New Issue
Block a user