feat(gtm-manager): Rename to ourdigital-gtm-manager and add dataLayer injector
BREAKING CHANGE: Renamed from 13-gtm-audit to 13-ourdigital-gtm-manager New Features: - DataLayerInjector class for generating custom HTML tags - Support for 20+ GA4 event types (ecommerce, forms, video, engagement) - Subcommand structure: audit and inject modes - Preset tag generation (ecommerce, engagement, all) - DOM scraping option for dynamic value extraction - Generate tags from audit report findings - Korean payment method support (카카오페이, 네이버페이, 토스) CLI Changes: - `python gtm_manager.py audit --url ...` for auditing - `python gtm_manager.py inject --preset ecommerce` for tag generation - `python gtm_manager.py inject --event purchase --event add_to_cart` - `python gtm_manager.py inject --from-audit report.json` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
# Common GTM Issues & Fixes
|
||||
|
||||
## Container Issues
|
||||
|
||||
### GTM Not Firing
|
||||
**Symptoms**: No GTM requests in network tab
|
||||
**Causes**:
|
||||
1. Script blocked by ad blocker
|
||||
2. Script placed after closing body tag
|
||||
3. JavaScript error before GTM loads
|
||||
4. Consent management blocking GTM
|
||||
|
||||
**Fix**:
|
||||
```html
|
||||
<!-- Place immediately after opening <head> tag -->
|
||||
<script>(function(w,d,s,l,i){...})(window,document,'script','dataLayer','GTM-XXXXXX');</script>
|
||||
```
|
||||
|
||||
### Multiple Containers Conflict
|
||||
**Symptoms**: Duplicate events, inconsistent data
|
||||
**Causes**:
|
||||
1. Legacy container not removed
|
||||
2. Different teams installed separate containers
|
||||
3. Theme/plugin auto-installed GTM
|
||||
|
||||
**Fix**:
|
||||
1. Audit all containers in source
|
||||
2. Consolidate to single container
|
||||
3. Use GTM environments for staging/prod
|
||||
|
||||
### Container ID Mismatch
|
||||
**Symptoms**: Tags not firing, wrong property receiving data
|
||||
**Causes**:
|
||||
1. Dev/staging container on production
|
||||
2. Copy-paste error during installation
|
||||
|
||||
**Fix**: Verify container ID matches GTM account
|
||||
|
||||
---
|
||||
|
||||
## DataLayer Issues
|
||||
|
||||
### DataLayer Not Initialized
|
||||
**Symptoms**: First push events lost
|
||||
**Code Error**:
|
||||
```javascript
|
||||
// Wrong - GTM loads before dataLayer exists
|
||||
<script>GTM snippet</script>
|
||||
dataLayer.push({...});
|
||||
```
|
||||
|
||||
**Fix**:
|
||||
```javascript
|
||||
// Correct - Initialize dataLayer first
|
||||
<script>window.dataLayer = window.dataLayer || [];</script>
|
||||
<script>GTM snippet</script>
|
||||
```
|
||||
|
||||
### Case Sensitivity Issues
|
||||
**Symptoms**: Triggers not matching
|
||||
**Example**:
|
||||
```javascript
|
||||
// DataLayer pushes "AddToCart"
|
||||
dataLayer.push({ event: "AddToCart" });
|
||||
|
||||
// But GTM trigger looks for "addToCart" - won't match!
|
||||
```
|
||||
|
||||
**Fix**: Standardize event naming (recommend lowercase with underscores)
|
||||
|
||||
### Wrong Data Types
|
||||
**Symptoms**: Calculations wrong in GA4, missing data
|
||||
**Example**:
|
||||
```javascript
|
||||
// Wrong - price as string
|
||||
dataLayer.push({ ecommerce: { value: "29.99" }});
|
||||
|
||||
// Correct - price as number
|
||||
dataLayer.push({ ecommerce: { value: 29.99 }});
|
||||
```
|
||||
|
||||
### Timing Issues
|
||||
**Symptoms**: Events fire before data available
|
||||
**Cause**: DataLayer push happens after tag fires
|
||||
|
||||
**Fix**: Use "Custom Event" trigger instead of "Page View"
|
||||
|
||||
---
|
||||
|
||||
## Tag Issues
|
||||
|
||||
### Tag Not Firing
|
||||
|
||||
**Checklist**:
|
||||
1. ✓ Trigger conditions met?
|
||||
2. ✓ Trigger enabled?
|
||||
3. ✓ Tag not paused?
|
||||
4. ✓ No blocking triggers active?
|
||||
5. ✓ Consent mode not blocking?
|
||||
|
||||
**Debug Steps**:
|
||||
1. GTM Preview > Check Tags Fired
|
||||
2. Verify trigger shows green check
|
||||
3. Check Variables tab for expected values
|
||||
|
||||
### Duplicate Tag Firing
|
||||
**Symptoms**: Events counted 2x in GA4
|
||||
**Causes**:
|
||||
1. Multiple triggers on same action
|
||||
2. Page re-renders triggering again
|
||||
3. SPA virtual pageviews firing multiple times
|
||||
|
||||
**Fix**:
|
||||
1. Add "Once per event" tag firing option
|
||||
2. Use trigger groups to control firing
|
||||
3. Add conditions to prevent re-firing
|
||||
|
||||
### Wrong Parameters Sent
|
||||
**Symptoms**: Data appears in wrong fields in GA4
|
||||
**Debug**:
|
||||
1. GTM Preview > Tags > Show fired tag
|
||||
2. Check "Values" sent with tag
|
||||
3. Compare with expected parameters
|
||||
|
||||
---
|
||||
|
||||
## E-commerce Issues
|
||||
|
||||
### Missing Transaction ID
|
||||
**Symptoms**: Duplicate purchases counted
|
||||
**Fix**: Ensure unique `transaction_id` generated server-side
|
||||
|
||||
### Items Array Empty
|
||||
**Symptoms**: Revenue tracked but no products
|
||||
**Check**: `ecommerce.items` array populated
|
||||
|
||||
### Value Mismatch
|
||||
**Symptoms**: Revenue doesn't match actual
|
||||
**Causes**:
|
||||
1. Tax/shipping included inconsistently
|
||||
2. Currency conversion issues
|
||||
3. Discount applied incorrectly
|
||||
|
||||
### Purchase Event Fires Multiple Times
|
||||
**Symptoms**: Same order tracked 2-3x
|
||||
**Causes**:
|
||||
1. Page refresh on confirmation
|
||||
2. Browser back button
|
||||
3. Email link revisit
|
||||
|
||||
**Fix**:
|
||||
```javascript
|
||||
// Check if already tracked
|
||||
if (!sessionStorage.getItem('purchase_' + transaction_id)) {
|
||||
dataLayer.push({ event: 'purchase', ... });
|
||||
sessionStorage.setItem('purchase_' + transaction_id, 'true');
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Consent Mode Issues
|
||||
|
||||
### Tags Blocked by Consent
|
||||
**Symptoms**: Tags show "Blocked by consent" in Preview
|
||||
**Fix**:
|
||||
1. Verify consent mode implementation
|
||||
2. Check default consent state
|
||||
3. Test with consent granted
|
||||
|
||||
### Consent Not Updating
|
||||
**Symptoms**: Tags stay blocked after user accepts
|
||||
**Fix**: Verify `gtag('consent', 'update', {...})` fires on accept
|
||||
|
||||
---
|
||||
|
||||
## SPA (Single Page App) Issues
|
||||
|
||||
### Pageviews Not Tracking Navigation
|
||||
**Symptoms**: Only initial pageview tracked
|
||||
**Cause**: No page reload on route change
|
||||
|
||||
**Fix**: Implement History Change trigger or custom event:
|
||||
```javascript
|
||||
// On route change
|
||||
dataLayer.push({
|
||||
event: 'virtual_pageview',
|
||||
page_path: newPath,
|
||||
page_title: newTitle
|
||||
});
|
||||
```
|
||||
|
||||
### Events Fire on Old Page Data
|
||||
**Symptoms**: Wrong page_path in events
|
||||
**Fix**: Update page variables before event push
|
||||
|
||||
---
|
||||
|
||||
## Performance Issues
|
||||
|
||||
### Tags Slowing Page Load
|
||||
**Symptoms**: High LCP, slow TTI
|
||||
**Causes**:
|
||||
1. Too many synchronous tags
|
||||
2. Large third-party scripts
|
||||
3. Tags in wrong firing sequence
|
||||
|
||||
**Fix**:
|
||||
1. Use tag sequencing
|
||||
2. Load non-critical tags on Window Loaded
|
||||
3. Defer marketing tags
|
||||
Reference in New Issue
Block a user