update:new skills and settings. new remote repository is set
This commit is contained in:
@@ -31,7 +31,11 @@
|
|||||||
"mcp__plugin_figma_figma__whoami",
|
"mcp__plugin_figma_figma__whoami",
|
||||||
"mcp__plugin_figma_figma__get_metadata",
|
"mcp__plugin_figma_figma__get_metadata",
|
||||||
"mcp__plugin_figma_figma__get_screenshot",
|
"mcp__plugin_figma_figma__get_screenshot",
|
||||||
"WebSearch"
|
"WebSearch",
|
||||||
|
"Bash(git -C ~/Workspace/seo-workspace rm:*)",
|
||||||
|
"Bash(git -C ~/Workspace/seo-workspace check-ignore -q \".claude/commands\")",
|
||||||
|
"Bash(git pull:*)",
|
||||||
|
"Bash(bash:*)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,142 +0,0 @@
|
|||||||
# OurDigital GTM Manager
|
|
||||||
|
|
||||||
Comprehensive Google Tag Manager management toolkit powered by Playwright.
|
|
||||||
|
|
||||||
> **Note**: For lightweight audit-only functionality, see [13-ourdigital-gtm-audit](../13-ourdigital-gtm-audit/).
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- **Audit Mode**: Validate GTM installations, dataLayer events, forms, and checkout flows
|
|
||||||
- **Inject Mode**: Generate custom HTML tags for dataLayer pushes
|
|
||||||
- **Container Detection**: Verify GTM installation, position, and duplicates
|
|
||||||
- **DataLayer Validation**: Event structure, types, sequence checking
|
|
||||||
- **Form Tracking**: Form discovery, field analysis, event verification
|
|
||||||
- **E-commerce Checkout**: Full funnel flow simulation and validation
|
|
||||||
- **Multi-Platform**: GA4, Meta Pixel, LinkedIn, Google Ads, Kakao, Naver
|
|
||||||
- **Notion Integration**: Export audit results to Notion database
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ourdigital-gtm-manager
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
pip install -r requirements.txt
|
|
||||||
|
|
||||||
# Install Playwright browsers
|
|
||||||
playwright install chromium
|
|
||||||
```
|
|
||||||
|
|
||||||
## Audit Mode
|
|
||||||
|
|
||||||
Analyze existing GTM implementations:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Full audit
|
|
||||||
python gtm_manager.py audit --url "https://yoursite.com" --journey full
|
|
||||||
|
|
||||||
# Specific container validation
|
|
||||||
python gtm_manager.py audit --url "https://yoursite.com" --container "GTM-XXXXXX"
|
|
||||||
|
|
||||||
# Form tracking only
|
|
||||||
python gtm_manager.py audit --url "https://yoursite.com/contact" --journey form
|
|
||||||
|
|
||||||
# Audit and generate missing tags
|
|
||||||
python gtm_manager.py audit --url "https://yoursite.com" --generate-tags
|
|
||||||
|
|
||||||
# Export to Notion
|
|
||||||
python gtm_manager.py audit --url "https://yoursite.com" --notion
|
|
||||||
```
|
|
||||||
|
|
||||||
### Audit Options
|
|
||||||
|
|
||||||
| Option | Description | Default |
|
|
||||||
|--------|-------------|---------|
|
|
||||||
| `--url` | Target URL (required) | - |
|
|
||||||
| `--container` | Expected GTM container ID | None |
|
|
||||||
| `--journey` | pageview, scroll, form, checkout, datalayer, full | full |
|
|
||||||
| `--output` | Output file path | gtm_audit_report.json |
|
|
||||||
| `--generate-tags` | Generate missing dataLayer tags | False |
|
|
||||||
| `--notion` | Export to Notion database | False |
|
|
||||||
|
|
||||||
## Inject Mode
|
|
||||||
|
|
||||||
Generate GTM custom HTML tags when you can't modify source code directly:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# List available event types
|
|
||||||
python gtm_manager.py inject --list-events
|
|
||||||
|
|
||||||
# Generate all ecommerce tags
|
|
||||||
python gtm_manager.py inject --preset ecommerce --output ./tags
|
|
||||||
|
|
||||||
# Generate specific events
|
|
||||||
python gtm_manager.py inject --event purchase --event add_to_cart
|
|
||||||
|
|
||||||
# Generate from audit report
|
|
||||||
python gtm_manager.py inject --from-audit gtm_audit_report.json
|
|
||||||
|
|
||||||
# Generate with DOM scraping code
|
|
||||||
python gtm_manager.py inject --event view_item --scrape
|
|
||||||
```
|
|
||||||
|
|
||||||
### Inject Options
|
|
||||||
|
|
||||||
| Option | Description | Default |
|
|
||||||
|--------|-------------|---------|
|
|
||||||
| `--event` | Event type(s) to generate | - |
|
|
||||||
| `--preset` | ecommerce, engagement, all | - |
|
|
||||||
| `--from-audit` | Generate from audit report | - |
|
|
||||||
| `--output` | Output directory | ./gtm_tags |
|
|
||||||
| `--format` | html or json | html |
|
|
||||||
| `--currency` | Currency code | KRW |
|
|
||||||
| `--scrape` | Generate DOM scraping code | False |
|
|
||||||
| `--list-events` | Show available events | - |
|
|
||||||
|
|
||||||
### Supported Events
|
|
||||||
|
|
||||||
**Ecommerce**: view_item, add_to_cart, remove_from_cart, view_cart, begin_checkout, add_shipping_info, add_payment_info, purchase
|
|
||||||
|
|
||||||
**Forms**: form_submit, form_start, generate_lead
|
|
||||||
|
|
||||||
**Engagement**: scroll, file_download, search, outbound_click, share
|
|
||||||
|
|
||||||
**Video**: video_start, video_progress, video_complete
|
|
||||||
|
|
||||||
**User**: login, sign_up, page_view
|
|
||||||
|
|
||||||
## Notion Integration
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Set Notion API token
|
|
||||||
export NOTION_TOKEN="secret_xxxxx"
|
|
||||||
|
|
||||||
# Export audit to Notion
|
|
||||||
python gtm_manager.py audit --url "https://yoursite.com" --notion --notion-detailed
|
|
||||||
```
|
|
||||||
|
|
||||||
## Using with Claude Code
|
|
||||||
|
|
||||||
This project includes a `CLAUDE.md` file optimized for Claude Code.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
claude
|
|
||||||
|
|
||||||
# Then ask Claude:
|
|
||||||
> Run a GTM audit on https://example.com
|
|
||||||
> Generate ecommerce dataLayer tags for my site
|
|
||||||
> Check the checkout flow and create missing tags
|
|
||||||
```
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
See `docs/` folder for:
|
|
||||||
- GA4 event specifications
|
|
||||||
- E-commerce dataLayer schemas
|
|
||||||
- Form tracking patterns
|
|
||||||
- Checkout flow sequences
|
|
||||||
- Common issues and fixes
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
MIT
|
|
||||||
@@ -1,219 +0,0 @@
|
|||||||
# OurDigital GTM Manager
|
|
||||||
|
|
||||||
Comprehensive Google Tag Manager management toolkit - audit, analyze, and generate dataLayer implementations.
|
|
||||||
|
|
||||||
> **Note**: For lightweight audit-only functionality, see [13-ourdigital-gtm-audit](../13-ourdigital-gtm-audit/).
|
|
||||||
|
|
||||||
## Project Overview
|
|
||||||
|
|
||||||
This tool provides two main capabilities:
|
|
||||||
1. **Audit**: Validate GTM installations, analyze dataLayer events, test form/checkout tracking
|
|
||||||
2. **Inject**: Generate custom HTML tags for dataLayer pushes when direct code access is unavailable
|
|
||||||
|
|
||||||
## Quick Commands
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Install dependencies
|
|
||||||
pip install playwright
|
|
||||||
playwright install chromium
|
|
||||||
|
|
||||||
# AUDIT MODE
|
|
||||||
# Run full audit
|
|
||||||
python gtm_manager.py audit --url "https://example.com" --journey full
|
|
||||||
|
|
||||||
# Audit with Notion export
|
|
||||||
python gtm_manager.py audit --url "https://example.com" --notion
|
|
||||||
|
|
||||||
# Audit and generate missing tags
|
|
||||||
python gtm_manager.py audit --url "https://example.com" --generate-tags
|
|
||||||
|
|
||||||
# INJECT MODE
|
|
||||||
# List available event types
|
|
||||||
python gtm_manager.py inject --list-events
|
|
||||||
|
|
||||||
# Generate all ecommerce tags
|
|
||||||
python gtm_manager.py inject --preset ecommerce --output ./tags
|
|
||||||
|
|
||||||
# Generate specific event tags
|
|
||||||
python gtm_manager.py inject --event purchase --event add_to_cart
|
|
||||||
|
|
||||||
# Generate from audit report
|
|
||||||
python gtm_manager.py inject --from-audit gtm_audit_report.json
|
|
||||||
|
|
||||||
# Generate with DOM scraping
|
|
||||||
python gtm_manager.py inject --event view_item --scrape
|
|
||||||
```
|
|
||||||
|
|
||||||
## Audit Mode
|
|
||||||
|
|
||||||
### Journey Types
|
|
||||||
|
|
||||||
| Journey | Description |
|
|
||||||
|---------|-------------|
|
|
||||||
| `pageview` | Basic page load + scroll simulation |
|
|
||||||
| `scroll` | Scroll depth trigger testing (25%, 50%, 75%, 90%) |
|
|
||||||
| `form` | Form discovery, field analysis, interaction simulation |
|
|
||||||
| `checkout` | E-commerce flow: cart → checkout → shipping → payment → purchase |
|
|
||||||
| `datalayer` | Deep dataLayer validation and event sequence analysis |
|
|
||||||
| `full` | All of the above combined |
|
|
||||||
|
|
||||||
### Audit Output
|
|
||||||
|
|
||||||
Generates `gtm_audit_report.json` with:
|
|
||||||
- Container status (installed, position, duplicates)
|
|
||||||
- DataLayer analysis (events, validation issues, sequence errors)
|
|
||||||
- Form analysis (forms found, tracking readiness, missing events)
|
|
||||||
- Checkout analysis (elements detected, flow issues)
|
|
||||||
- Network requests (GA4, Meta, LinkedIn, etc.)
|
|
||||||
- Recommendations and checklist
|
|
||||||
|
|
||||||
## Inject Mode
|
|
||||||
|
|
||||||
Generate GTM custom HTML tags for dataLayer injection when you can't modify source code directly.
|
|
||||||
|
|
||||||
### Event Categories
|
|
||||||
|
|
||||||
**Ecommerce:**
|
|
||||||
- `view_item`, `add_to_cart`, `remove_from_cart`, `view_cart`
|
|
||||||
- `begin_checkout`, `add_shipping_info`, `add_payment_info`, `purchase`
|
|
||||||
|
|
||||||
**Forms & Leads:**
|
|
||||||
- `form_submit`, `form_start`, `generate_lead`
|
|
||||||
|
|
||||||
**Engagement:**
|
|
||||||
- `scroll`, `file_download`, `search`, `outbound_click`, `share`
|
|
||||||
|
|
||||||
**Video:**
|
|
||||||
- `video_start`, `video_progress`, `video_complete`
|
|
||||||
|
|
||||||
**User:**
|
|
||||||
- `login`, `sign_up`, `page_view`
|
|
||||||
|
|
||||||
### Presets
|
|
||||||
|
|
||||||
| Preset | Events Included |
|
|
||||||
|--------|-----------------|
|
|
||||||
| `ecommerce` | All 8 ecommerce events |
|
|
||||||
| `engagement` | Forms, scroll, downloads, video, search, sharing |
|
|
||||||
| `all` | Everything including page_view, login, sign_up |
|
|
||||||
|
|
||||||
### Generated Tag Features
|
|
||||||
|
|
||||||
- GA4-compliant dataLayer structure
|
|
||||||
- Ecommerce object clearing before pushes
|
|
||||||
- DOM scraping option for dynamic values
|
|
||||||
- Trigger recommendations and selectors
|
|
||||||
- Korean payment method support
|
|
||||||
|
|
||||||
## Notion Integration
|
|
||||||
|
|
||||||
Export audit results directly to Notion database for tracking and collaboration.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Export to default Notion database (OurDigital GTM Audit Log)
|
|
||||||
python gtm_manager.py audit --url "https://example.com" --notion
|
|
||||||
|
|
||||||
# Export with detailed content
|
|
||||||
python gtm_manager.py audit --url "https://example.com" --notion --notion-detailed
|
|
||||||
```
|
|
||||||
|
|
||||||
### Environment Variables
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export NOTION_TOKEN="secret_xxxxx"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Default Database
|
|
||||||
|
|
||||||
Default Notion database: [OurDigital GTM Audit Log](https://www.notion.so/2cf581e58a1e8163997fccb387156a20)
|
|
||||||
|
|
||||||
## Key Files
|
|
||||||
|
|
||||||
- `gtm_manager.py` - Main script with audit and inject functionality
|
|
||||||
- `docs/ga4_events.md` - GA4 event specifications
|
|
||||||
- `docs/ecommerce_schema.md` - E-commerce dataLayer structures
|
|
||||||
- `docs/form_tracking.md` - Form event patterns
|
|
||||||
- `docs/checkout_flow.md` - Checkout funnel sequence
|
|
||||||
- `docs/datalayer_validation.md` - Validation rules
|
|
||||||
- `docs/common_issues.md` - Frequent problems and fixes
|
|
||||||
|
|
||||||
## Coding Guidelines
|
|
||||||
|
|
||||||
When modifying this tool:
|
|
||||||
|
|
||||||
1. **Tag Destinations**: Add new platforms to `TAG_DESTINATIONS` dict
|
|
||||||
2. **Event Validation**: Add requirements to `GA4_EVENT_REQUIREMENTS` dict
|
|
||||||
3. **Event Templates**: Add new events to `DataLayerInjector.EVENT_TEMPLATES`
|
|
||||||
4. **Form Selectors**: Extend `FormAnalyzer.discover_forms()` for custom forms
|
|
||||||
5. **Checkout Elements**: Add selectors to `CheckoutFlowAnalyzer.detect_checkout_elements()`
|
|
||||||
|
|
||||||
## Korean Market Considerations
|
|
||||||
|
|
||||||
- Support Korean payment methods (카카오페이, 네이버페이, 토스)
|
|
||||||
- Handle KRW currency (no decimals)
|
|
||||||
- Include Kakao Pixel and Naver Analytics patterns
|
|
||||||
- Korean button text patterns (장바구니, 결제하기, 주문하기)
|
|
||||||
|
|
||||||
## Common Tasks
|
|
||||||
|
|
||||||
### Add support for new tag platform
|
|
||||||
```python
|
|
||||||
# In TAG_DESTINATIONS dict
|
|
||||||
"NewPlatform": [
|
|
||||||
r"tracking\.newplatform\.com",
|
|
||||||
r"pixel\.newplatform\.com",
|
|
||||||
],
|
|
||||||
```
|
|
||||||
|
|
||||||
### Add new event type for injection
|
|
||||||
```python
|
|
||||||
# In DataLayerInjector.EVENT_TEMPLATES
|
|
||||||
"custom_event": {
|
|
||||||
"description": "Track custom action",
|
|
||||||
"params": {
|
|
||||||
"custom_param": "/* value */",
|
|
||||||
},
|
|
||||||
"trigger": "Custom Trigger",
|
|
||||||
},
|
|
||||||
```
|
|
||||||
|
|
||||||
### Extend checkout flow for specific platform
|
|
||||||
```python
|
|
||||||
# In CheckoutFlowAnalyzer.detect_checkout_elements()
|
|
||||||
# Add platform-specific selectors
|
|
||||||
```
|
|
||||||
|
|
||||||
## Notion Output (Required)
|
|
||||||
|
|
||||||
**IMPORTANT**: All GTM audit reports MUST be saved to the OurDigital GTM Audit Archive database.
|
|
||||||
|
|
||||||
### Database Configuration
|
|
||||||
|
|
||||||
| Field | Value |
|
|
||||||
|-------|-------|
|
|
||||||
| Database ID | `2cf581e5-8a1e-8163-997f-ccb387156a20` |
|
|
||||||
| URL | https://www.notion.so/dintelligence/OurDigital-GTM-Audit-Archive-2cf581e58a1e80c8b358f1625356e931 |
|
|
||||||
|
|
||||||
### Required Properties
|
|
||||||
|
|
||||||
| Property | Type | Description |
|
|
||||||
|----------|------|-------------|
|
|
||||||
| Site | Title | Site name or domain |
|
|
||||||
| URL | URL | Audited page URL |
|
|
||||||
| Audit Date | Date | Audit date (YYYY-MM-DD) |
|
|
||||||
| Audit ID | Rich Text | Format: GTM-YYYYMMDD-NNN |
|
|
||||||
| Audit Status | Select | Pass, Warning, Fail |
|
|
||||||
| GTM Status | Select | Installed, Not Found, Multiple Containers |
|
|
||||||
| Journey Type | Select | full, pageview, scroll, form, checkout, datalayer |
|
|
||||||
| Tags Fired | Multi-select | GA4, Google Ads, Meta Pixel, LinkedIn, TikTok, Kakao, Naver |
|
|
||||||
| Container IDs | Rich Text | GTM container ID(s) |
|
|
||||||
| Issues Count | Number | Total issues found |
|
|
||||||
| Critical Issues | Number | Critical issues count |
|
|
||||||
| Summary | Rich Text | Brief audit summary |
|
|
||||||
|
|
||||||
### Language Guidelines
|
|
||||||
|
|
||||||
- Report content in Korean (한국어)
|
|
||||||
- Keep technical English terms as-is (e.g., GTM, dataLayer, GA4)
|
|
||||||
- URLs and code remain unchanged
|
|
||||||
|
|
||||||
@@ -1,237 +0,0 @@
|
|||||||
# E-commerce Checkout Flow Reference
|
|
||||||
|
|
||||||
## Complete Checkout Event Sequence
|
|
||||||
|
|
||||||
```
|
|
||||||
view_cart → begin_checkout → add_shipping_info → add_payment_info → purchase
|
|
||||||
```
|
|
||||||
|
|
||||||
Each step must fire in order with consistent item data.
|
|
||||||
|
|
||||||
## Event Details
|
|
||||||
|
|
||||||
### 1. view_cart
|
|
||||||
When user views cart page.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
event: "view_cart",
|
|
||||||
ecommerce: {
|
|
||||||
currency: "KRW",
|
|
||||||
value: 125000,
|
|
||||||
items: [{
|
|
||||||
item_id: "SKU_001",
|
|
||||||
item_name: "Blue T-Shirt",
|
|
||||||
price: 45000,
|
|
||||||
quantity: 2,
|
|
||||||
item_brand: "Brand",
|
|
||||||
item_category: "Apparel"
|
|
||||||
}, {
|
|
||||||
item_id: "SKU_002",
|
|
||||||
item_name: "Black Jeans",
|
|
||||||
price: 35000,
|
|
||||||
quantity: 1
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. begin_checkout
|
|
||||||
When user initiates checkout process.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
event: "begin_checkout",
|
|
||||||
ecommerce: {
|
|
||||||
currency: "KRW",
|
|
||||||
value: 125000,
|
|
||||||
coupon: "SUMMER10",
|
|
||||||
items: [/* same items as view_cart */]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. add_shipping_info
|
|
||||||
When user completes shipping step.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
event: "add_shipping_info",
|
|
||||||
ecommerce: {
|
|
||||||
currency: "KRW",
|
|
||||||
value: 125000,
|
|
||||||
coupon: "SUMMER10",
|
|
||||||
shipping_tier: "Express", // Required
|
|
||||||
items: [/* same items */]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
**shipping_tier values:**
|
|
||||||
- "Standard" / "일반배송"
|
|
||||||
- "Express" / "익일배송"
|
|
||||||
- "Same Day" / "당일배송"
|
|
||||||
- "Free" / "무료배송"
|
|
||||||
- "Store Pickup" / "매장픽업"
|
|
||||||
|
|
||||||
### 4. add_payment_info
|
|
||||||
When user enters payment details.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
event: "add_payment_info",
|
|
||||||
ecommerce: {
|
|
||||||
currency: "KRW",
|
|
||||||
value: 125000,
|
|
||||||
coupon: "SUMMER10",
|
|
||||||
payment_type: "Credit Card", // Required
|
|
||||||
items: [/* same items */]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
**payment_type values:**
|
|
||||||
- "Credit Card" / "신용카드"
|
|
||||||
- "Debit Card" / "체크카드"
|
|
||||||
- "Bank Transfer" / "계좌이체"
|
|
||||||
- "Virtual Account" / "가상계좌"
|
|
||||||
- "Mobile Payment" / "휴대폰결제"
|
|
||||||
- "Kakao Pay" / "카카오페이"
|
|
||||||
- "Naver Pay" / "네이버페이"
|
|
||||||
- "Toss" / "토스"
|
|
||||||
- "PayPal"
|
|
||||||
|
|
||||||
### 5. purchase
|
|
||||||
When transaction completes successfully.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
event: "purchase",
|
|
||||||
ecommerce: {
|
|
||||||
transaction_id: "T_20250115_001234", // Required, unique
|
|
||||||
value: 130500, // Required (total)
|
|
||||||
tax: 11863,
|
|
||||||
shipping: 5000,
|
|
||||||
currency: "KRW", // Required
|
|
||||||
coupon: "SUMMER10",
|
|
||||||
items: [{
|
|
||||||
item_id: "SKU_001",
|
|
||||||
item_name: "Blue T-Shirt",
|
|
||||||
affiliation: "Online Store",
|
|
||||||
coupon: "SUMMER10",
|
|
||||||
discount: 4500,
|
|
||||||
price: 45000,
|
|
||||||
quantity: 2
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Funnel Drop-off Analysis
|
|
||||||
|
|
||||||
### Tracking Drop-offs
|
|
||||||
Monitor completion rate at each step:
|
|
||||||
|
|
||||||
| Step | Event | Drop-off Indicator |
|
|
||||||
|------|-------|-------------------|
|
|
||||||
| Cart | view_cart | User leaves cart page |
|
|
||||||
| Checkout Start | begin_checkout | User doesn't proceed |
|
|
||||||
| Shipping | add_shipping_info | Address form abandoned |
|
|
||||||
| Payment | add_payment_info | Payment not completed |
|
|
||||||
| Complete | purchase | Transaction failed |
|
|
||||||
|
|
||||||
### Implementing Drop-off Tracking
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Track checkout step viewed but not completed
|
|
||||||
let checkoutStep = 0;
|
|
||||||
|
|
||||||
function trackCheckoutProgress(step) {
|
|
||||||
if (step > checkoutStep) {
|
|
||||||
checkoutStep = step;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('beforeunload', () => {
|
|
||||||
if (checkoutStep > 0 && checkoutStep < 5) {
|
|
||||||
dataLayer.push({
|
|
||||||
event: 'checkout_abandon',
|
|
||||||
last_step: checkoutStep,
|
|
||||||
step_name: ['cart', 'checkout', 'shipping', 'payment', 'complete'][checkoutStep - 1]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Value Consistency Check
|
|
||||||
|
|
||||||
Ensure `value` matches across events:
|
|
||||||
|
|
||||||
```
|
|
||||||
view_cart.value = sum(items.price * items.quantity)
|
|
||||||
begin_checkout.value = view_cart.value
|
|
||||||
add_shipping_info.value = begin_checkout.value
|
|
||||||
add_payment_info.value = add_shipping_info.value
|
|
||||||
purchase.value = add_payment_info.value + shipping + tax - discount
|
|
||||||
```
|
|
||||||
|
|
||||||
## Common Issues
|
|
||||||
|
|
||||||
### Duplicate Purchase Events
|
|
||||||
**Problem**: Same order tracked multiple times
|
|
||||||
**Solution**:
|
|
||||||
```javascript
|
|
||||||
// Check if already tracked
|
|
||||||
const txId = "T_12345";
|
|
||||||
if (!sessionStorage.getItem('purchase_' + txId)) {
|
|
||||||
dataLayer.push({ event: 'purchase', ... });
|
|
||||||
sessionStorage.setItem('purchase_' + txId, 'true');
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Missing Items in Later Steps
|
|
||||||
**Problem**: Items present in view_cart but missing in purchase
|
|
||||||
**Solution**: Store cart data in session and reuse
|
|
||||||
|
|
||||||
### Inconsistent Currency
|
|
||||||
**Problem**: Some events use USD, others KRW
|
|
||||||
**Solution**: Standardize currency across all events
|
|
||||||
|
|
||||||
### Wrong Value Calculation
|
|
||||||
**Problem**: purchase.value doesn't include tax/shipping
|
|
||||||
**Solution**:
|
|
||||||
```
|
|
||||||
purchase.value = subtotal + tax + shipping - discount
|
|
||||||
```
|
|
||||||
|
|
||||||
## Korean E-commerce Platforms
|
|
||||||
|
|
||||||
### Cafe24
|
|
||||||
Custom dataLayer variable names - check documentation
|
|
||||||
|
|
||||||
### Shopify Korea
|
|
||||||
Standard GA4 format with `Shopify.checkout` object
|
|
||||||
|
|
||||||
### WooCommerce
|
|
||||||
Use official GA4 plugin or custom implementation
|
|
||||||
|
|
||||||
### Naver SmartStore
|
|
||||||
Separate Naver Analytics implementation required
|
|
||||||
|
|
||||||
## Checkout Flow Checklist
|
|
||||||
|
|
||||||
- [ ] view_cart fires on cart page load
|
|
||||||
- [ ] begin_checkout fires on checkout button click
|
|
||||||
- [ ] add_shipping_info includes shipping_tier
|
|
||||||
- [ ] add_payment_info includes payment_type
|
|
||||||
- [ ] purchase has unique transaction_id
|
|
||||||
- [ ] All events have consistent items array
|
|
||||||
- [ ] Currency is consistent across all events
|
|
||||||
- [ ] Value calculations are accurate
|
|
||||||
- [ ] ecommerce object cleared before each push
|
|
||||||
- [ ] Purchase event fires only once per order
|
|
||||||
@@ -1,287 +0,0 @@
|
|||||||
# DataLayer Validation Reference
|
|
||||||
|
|
||||||
## DataLayer Structure Basics
|
|
||||||
|
|
||||||
### Proper Initialization
|
|
||||||
```javascript
|
|
||||||
// Must appear BEFORE GTM script
|
|
||||||
<script>
|
|
||||||
window.dataLayer = window.dataLayer || [];
|
|
||||||
</script>
|
|
||||||
<!-- GTM script here -->
|
|
||||||
```
|
|
||||||
|
|
||||||
### Push Syntax
|
|
||||||
```javascript
|
|
||||||
// Correct
|
|
||||||
dataLayer.push({ event: "page_view", page_title: "Home" });
|
|
||||||
|
|
||||||
// Wrong - direct assignment
|
|
||||||
dataLayer = [{ event: "page_view" }]; // ❌ Overwrites array
|
|
||||||
```
|
|
||||||
|
|
||||||
## Validation Rules
|
|
||||||
|
|
||||||
### Event Names
|
|
||||||
|
|
||||||
| Rule | Valid | Invalid |
|
|
||||||
|------|-------|---------|
|
|
||||||
| Alphanumeric + underscore | `add_to_cart` | `add-to-cart` |
|
|
||||||
| Max 40 characters | `purchase` | (too long names) |
|
|
||||||
| Case sensitive | `addToCart` ≠ `addtocart` | - |
|
|
||||||
| No spaces | `form_submit` | `form submit` |
|
|
||||||
| No special chars | `click_cta` | `click@cta` |
|
|
||||||
|
|
||||||
### Parameter Names
|
|
||||||
|
|
||||||
| Rule | Valid | Invalid |
|
|
||||||
|------|-------|---------|
|
|
||||||
| Max 40 characters | `item_category` | (too long) |
|
|
||||||
| Alphanumeric + underscore | `user_id` | `user-id` |
|
|
||||||
| Cannot start with `_` | `custom_param` | `_private` |
|
|
||||||
| Cannot start with number | `step_1` | `1_step` |
|
|
||||||
|
|
||||||
### Data Types
|
|
||||||
|
|
||||||
| Parameter | Expected Type | Example |
|
|
||||||
|-----------|---------------|---------|
|
|
||||||
| value | number | `29.99` not `"29.99"` |
|
|
||||||
| currency | string (ISO 4217) | `"USD"`, `"KRW"` |
|
|
||||||
| transaction_id | string | `"T_12345"` |
|
|
||||||
| quantity | integer | `2` not `2.0` |
|
|
||||||
| price | number | `45000` |
|
|
||||||
| items | array | `[{...}, {...}]` |
|
|
||||||
|
|
||||||
### Type Validation Code
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
function validateDataLayerPush(data) {
|
|
||||||
const issues = [];
|
|
||||||
|
|
||||||
// Check value is number
|
|
||||||
if (data.ecommerce?.value !== undefined) {
|
|
||||||
if (typeof data.ecommerce.value !== 'number') {
|
|
||||||
issues.push(`value should be number, got ${typeof data.ecommerce.value}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check currency format
|
|
||||||
if (data.ecommerce?.currency) {
|
|
||||||
if (!/^[A-Z]{3}$/.test(data.ecommerce.currency)) {
|
|
||||||
issues.push(`currency should be 3-letter ISO code`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check items array
|
|
||||||
if (data.ecommerce?.items) {
|
|
||||||
if (!Array.isArray(data.ecommerce.items)) {
|
|
||||||
issues.push(`items should be array`);
|
|
||||||
} else {
|
|
||||||
data.ecommerce.items.forEach((item, i) => {
|
|
||||||
if (!item.item_id) issues.push(`items[${i}] missing item_id`);
|
|
||||||
if (!item.item_name) issues.push(`items[${i}] missing item_name`);
|
|
||||||
if (item.price && typeof item.price !== 'number') {
|
|
||||||
issues.push(`items[${i}].price should be number`);
|
|
||||||
}
|
|
||||||
if (item.quantity && !Number.isInteger(item.quantity)) {
|
|
||||||
issues.push(`items[${i}].quantity should be integer`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return issues;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## E-commerce Object Clearing
|
|
||||||
|
|
||||||
### Why Clear?
|
|
||||||
GA4 may merge previous ecommerce data with new events.
|
|
||||||
|
|
||||||
### Correct Pattern
|
|
||||||
```javascript
|
|
||||||
// Clear first
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
|
|
||||||
// Then push new event
|
|
||||||
dataLayer.push({
|
|
||||||
event: "view_item",
|
|
||||||
ecommerce: { ... }
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Validation Check
|
|
||||||
```javascript
|
|
||||||
function checkEcommerceClear(dataLayerArray) {
|
|
||||||
let lastHadEcommerce = false;
|
|
||||||
const issues = [];
|
|
||||||
|
|
||||||
dataLayerArray.forEach((item, i) => {
|
|
||||||
const hasEcommerce = 'ecommerce' in item;
|
|
||||||
const isNull = item.ecommerce === null;
|
|
||||||
|
|
||||||
if (hasEcommerce && !isNull && lastHadEcommerce) {
|
|
||||||
issues.push({
|
|
||||||
index: i,
|
|
||||||
message: 'Missing ecommerce:null before this push'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
lastHadEcommerce = hasEcommerce && !isNull;
|
|
||||||
});
|
|
||||||
|
|
||||||
return issues;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Event Sequence Validation
|
|
||||||
|
|
||||||
### Expected Sequences
|
|
||||||
|
|
||||||
**E-commerce Purchase Flow:**
|
|
||||||
```
|
|
||||||
view_item_list? → view_item → add_to_cart → view_cart →
|
|
||||||
begin_checkout → add_shipping_info → add_payment_info → purchase
|
|
||||||
```
|
|
||||||
|
|
||||||
**Form Submission:**
|
|
||||||
```
|
|
||||||
form_start → form_submit → generate_lead?
|
|
||||||
```
|
|
||||||
|
|
||||||
**User Authentication:**
|
|
||||||
```
|
|
||||||
login | sign_up
|
|
||||||
```
|
|
||||||
|
|
||||||
### Sequence Validator
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
function validateSequence(events, expectedOrder) {
|
|
||||||
const eventNames = events
|
|
||||||
.filter(e => e.event)
|
|
||||||
.map(e => e.event);
|
|
||||||
|
|
||||||
let lastIndex = -1;
|
|
||||||
const issues = [];
|
|
||||||
|
|
||||||
eventNames.forEach(event => {
|
|
||||||
const index = expectedOrder.indexOf(event);
|
|
||||||
if (index !== -1) {
|
|
||||||
if (index < lastIndex) {
|
|
||||||
issues.push(`${event} fired out of expected order`);
|
|
||||||
}
|
|
||||||
lastIndex = index;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return issues;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Duplicate Event Detection
|
|
||||||
|
|
||||||
### Common Duplicates
|
|
||||||
- Multiple `page_view` on single page load
|
|
||||||
- `purchase` firing on page refresh
|
|
||||||
- Click events on bubbling elements
|
|
||||||
|
|
||||||
### Detection Code
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
function findDuplicates(events) {
|
|
||||||
const seen = {};
|
|
||||||
const duplicates = [];
|
|
||||||
|
|
||||||
events.forEach((event, i) => {
|
|
||||||
if (!event.event) return;
|
|
||||||
|
|
||||||
const key = JSON.stringify(event);
|
|
||||||
if (seen[key]) {
|
|
||||||
duplicates.push({
|
|
||||||
event: event.event,
|
|
||||||
firstIndex: seen[key],
|
|
||||||
duplicateIndex: i
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
seen[key] = i;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return duplicates;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Real-time Monitoring Setup
|
|
||||||
|
|
||||||
### Console Monitoring
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Paste in browser console to monitor pushes
|
|
||||||
(function() {
|
|
||||||
const original = dataLayer.push;
|
|
||||||
dataLayer.push = function() {
|
|
||||||
console.group('📊 dataLayer.push');
|
|
||||||
console.log('Data:', arguments[0]);
|
|
||||||
console.log('Time:', new Date().toISOString());
|
|
||||||
console.groupEnd();
|
|
||||||
return original.apply(this, arguments);
|
|
||||||
};
|
|
||||||
console.log('✅ DataLayer monitoring active');
|
|
||||||
})();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Export DataLayer
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Copy full dataLayer to clipboard
|
|
||||||
copy(JSON.stringify(dataLayer, null, 2));
|
|
||||||
```
|
|
||||||
|
|
||||||
## Validation Checklist
|
|
||||||
|
|
||||||
### Structure
|
|
||||||
- [ ] dataLayer initialized before GTM
|
|
||||||
- [ ] Using push() not assignment
|
|
||||||
- [ ] Event names follow conventions
|
|
||||||
- [ ] Parameter names follow conventions
|
|
||||||
|
|
||||||
### Data Types
|
|
||||||
- [ ] value is number
|
|
||||||
- [ ] currency is 3-letter code
|
|
||||||
- [ ] quantity is integer
|
|
||||||
- [ ] items is array
|
|
||||||
- [ ] Required fields present
|
|
||||||
|
|
||||||
### E-commerce
|
|
||||||
- [ ] ecommerce:null before each push
|
|
||||||
- [ ] items array has item_id and item_name
|
|
||||||
- [ ] transaction_id is unique
|
|
||||||
- [ ] Consistent currency across events
|
|
||||||
|
|
||||||
### Sequence
|
|
||||||
- [ ] Events fire in logical order
|
|
||||||
- [ ] No duplicate events
|
|
||||||
- [ ] Purchase fires only once
|
|
||||||
|
|
||||||
## Debug Tools
|
|
||||||
|
|
||||||
### GTM Preview Mode
|
|
||||||
- Real-time event inspection
|
|
||||||
- Variable value checking
|
|
||||||
- Tag firing verification
|
|
||||||
|
|
||||||
### GA4 DebugView
|
|
||||||
- Live event stream
|
|
||||||
- Parameter validation
|
|
||||||
- User property tracking
|
|
||||||
|
|
||||||
### Browser Console
|
|
||||||
```javascript
|
|
||||||
// View current dataLayer
|
|
||||||
console.table(dataLayer);
|
|
||||||
|
|
||||||
// Filter by event
|
|
||||||
dataLayer.filter(d => d.event === 'purchase');
|
|
||||||
```
|
|
||||||
@@ -1,216 +0,0 @@
|
|||||||
# E-commerce DataLayer Schema Reference
|
|
||||||
|
|
||||||
## GA4 E-commerce Structure
|
|
||||||
|
|
||||||
### Items Array Schema
|
|
||||||
Every e-commerce event requires an `items` array:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
items: [{
|
|
||||||
// Required
|
|
||||||
item_id: "SKU_12345",
|
|
||||||
item_name: "Blue T-Shirt",
|
|
||||||
|
|
||||||
// Recommended
|
|
||||||
affiliation: "Store Name",
|
|
||||||
coupon: "SUMMER_SALE",
|
|
||||||
discount: 5.00,
|
|
||||||
index: 0,
|
|
||||||
item_brand: "Brand Name",
|
|
||||||
item_category: "Apparel",
|
|
||||||
item_category2: "Men",
|
|
||||||
item_category3: "Shirts",
|
|
||||||
item_category4: "T-Shirts",
|
|
||||||
item_category5: "Short Sleeve",
|
|
||||||
item_list_id: "related_products",
|
|
||||||
item_list_name: "Related Products",
|
|
||||||
item_variant: "Blue/Large",
|
|
||||||
location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
|
|
||||||
price: 29.99,
|
|
||||||
quantity: 1
|
|
||||||
}]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Clear Previous E-commerce Data
|
|
||||||
Always clear before new e-commerce event:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
event: "view_item",
|
|
||||||
ecommerce: {
|
|
||||||
// new data
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Complete Purchase Flow
|
|
||||||
|
|
||||||
### 1. Product List View
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
event: "view_item_list",
|
|
||||||
ecommerce: {
|
|
||||||
item_list_id: "category_results",
|
|
||||||
item_list_name: "Category Results",
|
|
||||||
items: [
|
|
||||||
{ item_id: "SKU_001", item_name: "Product 1", index: 0, price: 29.99 },
|
|
||||||
{ item_id: "SKU_002", item_name: "Product 2", index: 1, price: 39.99 }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Product Click
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
event: "select_item",
|
|
||||||
ecommerce: {
|
|
||||||
item_list_id: "category_results",
|
|
||||||
item_list_name: "Category Results",
|
|
||||||
items: [{
|
|
||||||
item_id: "SKU_001",
|
|
||||||
item_name: "Product 1",
|
|
||||||
price: 29.99
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Product Detail View
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
event: "view_item",
|
|
||||||
ecommerce: {
|
|
||||||
currency: "USD",
|
|
||||||
value: 29.99,
|
|
||||||
items: [{
|
|
||||||
item_id: "SKU_001",
|
|
||||||
item_name: "Product 1",
|
|
||||||
item_brand: "Brand",
|
|
||||||
item_category: "Category",
|
|
||||||
price: 29.99,
|
|
||||||
quantity: 1
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Add to Cart
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
event: "add_to_cart",
|
|
||||||
ecommerce: {
|
|
||||||
currency: "USD",
|
|
||||||
value: 29.99,
|
|
||||||
items: [{
|
|
||||||
item_id: "SKU_001",
|
|
||||||
item_name: "Product 1",
|
|
||||||
price: 29.99,
|
|
||||||
quantity: 1
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. View Cart
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
event: "view_cart",
|
|
||||||
ecommerce: {
|
|
||||||
currency: "USD",
|
|
||||||
value: 59.98,
|
|
||||||
items: [
|
|
||||||
{ item_id: "SKU_001", item_name: "Product 1", price: 29.99, quantity: 1 },
|
|
||||||
{ item_id: "SKU_002", item_name: "Product 2", price: 29.99, quantity: 1 }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6. Begin Checkout
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
event: "begin_checkout",
|
|
||||||
ecommerce: {
|
|
||||||
currency: "USD",
|
|
||||||
value: 59.98,
|
|
||||||
coupon: "DISCOUNT10",
|
|
||||||
items: [...]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 7. Add Shipping Info
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
event: "add_shipping_info",
|
|
||||||
ecommerce: {
|
|
||||||
currency: "USD",
|
|
||||||
value: 59.98,
|
|
||||||
shipping_tier: "Standard",
|
|
||||||
items: [...]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 8. Add Payment Info
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
event: "add_payment_info",
|
|
||||||
ecommerce: {
|
|
||||||
currency: "USD",
|
|
||||||
value: 59.98,
|
|
||||||
payment_type: "Credit Card",
|
|
||||||
items: [...]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 9. Purchase
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
event: "purchase",
|
|
||||||
ecommerce: {
|
|
||||||
transaction_id: "T_12345",
|
|
||||||
value: 65.97,
|
|
||||||
tax: 4.99,
|
|
||||||
shipping: 5.99,
|
|
||||||
currency: "USD",
|
|
||||||
coupon: "DISCOUNT10",
|
|
||||||
items: [{
|
|
||||||
item_id: "SKU_001",
|
|
||||||
item_name: "Product 1",
|
|
||||||
affiliation: "Online Store",
|
|
||||||
coupon: "DISCOUNT10",
|
|
||||||
discount: 3.00,
|
|
||||||
item_brand: "Brand",
|
|
||||||
item_category: "Category",
|
|
||||||
price: 29.99,
|
|
||||||
quantity: 1
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Korean E-commerce Considerations
|
|
||||||
|
|
||||||
### Currency
|
|
||||||
```javascript
|
|
||||||
currency: "KRW",
|
|
||||||
value: 35000 // No decimals for KRW
|
|
||||||
```
|
|
||||||
|
|
||||||
### Common Korean Platform Integrations
|
|
||||||
- Cafe24: Uses custom dataLayer structure
|
|
||||||
- Shopify Korea: Standard GA4 format
|
|
||||||
- Naver SmartStore: Custom pixel implementation
|
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
# Form Tracking Reference
|
|
||||||
|
|
||||||
## GA4 Form Events
|
|
||||||
|
|
||||||
### form_start
|
|
||||||
Fires on first interaction with form field.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({
|
|
||||||
event: "form_start",
|
|
||||||
form_id: "contact-form",
|
|
||||||
form_name: "Contact Us",
|
|
||||||
form_destination: "/submit-contact"
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### form_submit
|
|
||||||
Fires on successful form submission.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({
|
|
||||||
event: "form_submit",
|
|
||||||
form_id: "contact-form",
|
|
||||||
form_name: "Contact Us",
|
|
||||||
form_destination: "/submit-contact",
|
|
||||||
form_submit_text: "Send Message"
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### generate_lead
|
|
||||||
Fires when form generates a qualified lead.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({
|
|
||||||
event: "generate_lead",
|
|
||||||
currency: "USD",
|
|
||||||
value: 100, // Estimated lead value
|
|
||||||
form_id: "quote-request"
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Form Field Events (Custom)
|
|
||||||
|
|
||||||
### field_focus
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({
|
|
||||||
event: "field_focus",
|
|
||||||
form_id: "signup-form",
|
|
||||||
field_name: "email",
|
|
||||||
field_type: "email"
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### field_complete
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({
|
|
||||||
event: "field_complete",
|
|
||||||
form_id: "signup-form",
|
|
||||||
field_name: "email",
|
|
||||||
field_type: "email",
|
|
||||||
is_valid: true
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### field_error
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({
|
|
||||||
event: "field_error",
|
|
||||||
form_id: "signup-form",
|
|
||||||
field_name: "email",
|
|
||||||
error_message: "Invalid email format"
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Form Abandonment Tracking
|
|
||||||
|
|
||||||
### Detecting Abandonment
|
|
||||||
Track when user leaves form without submitting:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Track form start
|
|
||||||
let formStarted = false;
|
|
||||||
document.querySelectorAll('form input, form select, form textarea')
|
|
||||||
.forEach(field => {
|
|
||||||
field.addEventListener('focus', function() {
|
|
||||||
if (!formStarted) {
|
|
||||||
formStarted = true;
|
|
||||||
dataLayer.push({ event: 'form_start', form_id: this.form.id });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Track abandonment on page leave
|
|
||||||
window.addEventListener('beforeunload', function() {
|
|
||||||
if (formStarted && !formSubmitted) {
|
|
||||||
dataLayer.push({
|
|
||||||
event: 'form_abandon',
|
|
||||||
form_id: 'contact-form',
|
|
||||||
last_field: lastFocusedField,
|
|
||||||
fields_completed: completedFieldCount
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## GTM Trigger Configuration
|
|
||||||
|
|
||||||
### Form Submission Trigger
|
|
||||||
| Setting | Value |
|
|
||||||
|---------|-------|
|
|
||||||
| Trigger Type | Form Submission |
|
|
||||||
| Wait for Tags | Check (if AJAX form) |
|
|
||||||
| Check Validation | Check |
|
|
||||||
| Form ID | equals `contact-form` |
|
|
||||||
|
|
||||||
### Form Start Trigger (Custom Event)
|
|
||||||
| Setting | Value |
|
|
||||||
|---------|-------|
|
|
||||||
| Trigger Type | Custom Event |
|
|
||||||
| Event Name | form_start |
|
|
||||||
| Fire On | All Custom Events |
|
|
||||||
|
|
||||||
## Common Form Types & Tracking
|
|
||||||
|
|
||||||
### Contact Forms
|
|
||||||
Events: `form_start`, `form_submit`, `generate_lead`
|
|
||||||
|
|
||||||
### Newsletter Signup
|
|
||||||
Events: `form_start`, `form_submit`, `sign_up`
|
|
||||||
|
|
||||||
### Login Forms
|
|
||||||
Events: `form_start`, `login`
|
|
||||||
|
|
||||||
### Search Forms
|
|
||||||
Events: `search` (with search_term parameter)
|
|
||||||
|
|
||||||
### Multi-Step Forms
|
|
||||||
Track each step:
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({
|
|
||||||
event: "form_step",
|
|
||||||
form_id: "checkout-form",
|
|
||||||
step_number: 2,
|
|
||||||
step_name: "Shipping Address"
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Validation Checklist
|
|
||||||
|
|
||||||
- [ ] Form has id or name attribute
|
|
||||||
- [ ] All required fields have names
|
|
||||||
- [ ] Submit button identifiable
|
|
||||||
- [ ] form_start fires on first interaction
|
|
||||||
- [ ] form_submit fires only on success
|
|
||||||
- [ ] generate_lead has value parameter
|
|
||||||
- [ ] Error events track validation failures
|
|
||||||
- [ ] Abandonment tracking implemented (optional)
|
|
||||||
@@ -1,177 +0,0 @@
|
|||||||
# GA4 Recommended Events Reference
|
|
||||||
|
|
||||||
## Automatically Collected Events
|
|
||||||
Events GA4 collects without configuration:
|
|
||||||
- `first_visit` - First time user visits
|
|
||||||
- `session_start` - Session begins
|
|
||||||
- `page_view` - Page loads (enhanced measurement)
|
|
||||||
- `scroll` - 90% scroll depth
|
|
||||||
- `click` - Outbound link clicks
|
|
||||||
- `file_download` - File download clicks
|
|
||||||
- `video_start`, `video_progress`, `video_complete` - YouTube embeds
|
|
||||||
|
|
||||||
## E-commerce Events (Required Parameters)
|
|
||||||
|
|
||||||
### view_item_list
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
event: "view_item_list",
|
|
||||||
ecommerce: {
|
|
||||||
item_list_id: "related_products",
|
|
||||||
item_list_name: "Related Products",
|
|
||||||
items: [{
|
|
||||||
item_id: "SKU_12345", // required
|
|
||||||
item_name: "Product Name", // required
|
|
||||||
price: 29.99,
|
|
||||||
quantity: 1
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### view_item
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
event: "view_item",
|
|
||||||
ecommerce: {
|
|
||||||
currency: "USD",
|
|
||||||
value: 29.99,
|
|
||||||
items: [{
|
|
||||||
item_id: "SKU_12345", // required
|
|
||||||
item_name: "Product Name", // required
|
|
||||||
price: 29.99,
|
|
||||||
quantity: 1
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### add_to_cart
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
event: "add_to_cart",
|
|
||||||
ecommerce: {
|
|
||||||
currency: "USD",
|
|
||||||
value: 29.99,
|
|
||||||
items: [{
|
|
||||||
item_id: "SKU_12345", // required
|
|
||||||
item_name: "Product Name", // required
|
|
||||||
price: 29.99,
|
|
||||||
quantity: 1
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### begin_checkout
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
event: "begin_checkout",
|
|
||||||
ecommerce: {
|
|
||||||
currency: "USD",
|
|
||||||
value: 99.99,
|
|
||||||
coupon: "SUMMER_SALE",
|
|
||||||
items: [...]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### add_payment_info
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
event: "add_payment_info",
|
|
||||||
ecommerce: {
|
|
||||||
currency: "USD",
|
|
||||||
value: 99.99,
|
|
||||||
payment_type: "credit_card",
|
|
||||||
items: [...]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### purchase
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
event: "purchase",
|
|
||||||
ecommerce: {
|
|
||||||
transaction_id: "T12345", // required, must be unique
|
|
||||||
value: 99.99, // required
|
|
||||||
currency: "USD", // required
|
|
||||||
tax: 4.99,
|
|
||||||
shipping: 5.99,
|
|
||||||
coupon: "SUMMER_SALE",
|
|
||||||
items: [{
|
|
||||||
item_id: "SKU_12345", // required
|
|
||||||
item_name: "Product Name",// required
|
|
||||||
price: 29.99,
|
|
||||||
quantity: 2
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Lead Generation Events
|
|
||||||
|
|
||||||
### generate_lead
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
event: "generate_lead",
|
|
||||||
currency: "USD",
|
|
||||||
value: 100 // estimated lead value
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### sign_up
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
event: "sign_up",
|
|
||||||
method: "email" // or "google", "facebook", etc.
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### login
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
event: "login",
|
|
||||||
method: "email"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Engagement Events
|
|
||||||
|
|
||||||
### search
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
event: "search",
|
|
||||||
search_term: "blue shoes"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### share
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
event: "share",
|
|
||||||
method: "twitter",
|
|
||||||
content_type: "article",
|
|
||||||
item_id: "article_123"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Parameter Validation Rules
|
|
||||||
|
|
||||||
| Parameter | Type | Max Length | Notes |
|
|
||||||
|-----------|------|------------|-------|
|
|
||||||
| event name | string | 40 chars | No spaces, alphanumeric + underscore |
|
|
||||||
| item_id | string | 100 chars | Required for e-commerce |
|
|
||||||
| item_name | string | 100 chars | Required for e-commerce |
|
|
||||||
| currency | string | 3 chars | ISO 4217 format (USD, KRW, etc.) |
|
|
||||||
| transaction_id | string | 100 chars | Must be unique per transaction |
|
|
||||||
| value | number | - | Numeric, no currency symbols |
|
|
||||||
|
|
||||||
## Common Validation Errors
|
|
||||||
|
|
||||||
1. **Missing required params**: `item_id` or `item_name` not in items array
|
|
||||||
2. **Wrong data type**: `value` as string instead of number
|
|
||||||
3. **Duplicate transaction_id**: Same ID used for multiple purchases
|
|
||||||
4. **Empty items array**: E-commerce event with no items
|
|
||||||
5. **Invalid currency**: Currency code not in ISO 4217 format
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
# GTM Audit Report Template
|
|
||||||
|
|
||||||
## Executive Summary
|
|
||||||
|
|
||||||
| Metric | Status |
|
|
||||||
|--------|--------|
|
|
||||||
| Container Installed | ✅ / ❌ |
|
|
||||||
| Container Valid | ✅ / ❌ |
|
|
||||||
| DataLayer Active | ✅ / ❌ |
|
|
||||||
| Tags Firing | X of Y |
|
|
||||||
| Critical Issues | X |
|
|
||||||
| Warnings | X |
|
|
||||||
|
|
||||||
## Container Status
|
|
||||||
|
|
||||||
**Container ID**: GTM-XXXXXX
|
|
||||||
**Installation Position**: head / body
|
|
||||||
**Multiple Containers**: Yes / No
|
|
||||||
**Noscript Fallback**: Present / Missing
|
|
||||||
|
|
||||||
### Issues Found
|
|
||||||
- [ ] Issue description
|
|
||||||
|
|
||||||
## DataLayer Analysis
|
|
||||||
|
|
||||||
### Events Captured
|
|
||||||
| Event Name | Count | Has Issues |
|
|
||||||
|------------|-------|------------|
|
|
||||||
| page_view | 1 | No |
|
|
||||||
| add_to_cart | 0 | - |
|
|
||||||
|
|
||||||
### DataLayer Quality
|
|
||||||
- [ ] Initialized before GTM
|
|
||||||
- [ ] Standard event naming
|
|
||||||
- [ ] Correct data types
|
|
||||||
- [ ] E-commerce structure valid
|
|
||||||
|
|
||||||
## Tag Firing Report
|
|
||||||
|
|
||||||
### Tags Fired ✅
|
|
||||||
| Destination | Events | Parameters |
|
|
||||||
|-------------|--------|------------|
|
|
||||||
| GA4 | page_view | page_location, page_title |
|
|
||||||
| Meta Pixel | PageView | - |
|
|
||||||
|
|
||||||
### Tags Not Detected ⚠️
|
|
||||||
| Expected Tag | Reason | Priority |
|
|
||||||
|--------------|--------|----------|
|
|
||||||
| GA4 purchase | Event not triggered | High |
|
|
||||||
|
|
||||||
## Network Request Analysis
|
|
||||||
|
|
||||||
Total requests captured: X
|
|
||||||
|
|
||||||
### By Destination
|
|
||||||
| Destination | Requests | Status |
|
|
||||||
|-------------|----------|--------|
|
|
||||||
| GA4 | X | ✅ |
|
|
||||||
| Meta | X | ✅ |
|
|
||||||
| Google Ads | 0 | ⚠️ |
|
|
||||||
|
|
||||||
## Issues & Recommendations
|
|
||||||
|
|
||||||
### Critical 🔴
|
|
||||||
1. **Issue Title**
|
|
||||||
- Description
|
|
||||||
- Impact
|
|
||||||
- Recommended Fix
|
|
||||||
|
|
||||||
### Warning 🟡
|
|
||||||
1. **Issue Title**
|
|
||||||
- Description
|
|
||||||
- Recommended Fix
|
|
||||||
|
|
||||||
### Info 🔵
|
|
||||||
1. **Issue Title**
|
|
||||||
- Description
|
|
||||||
|
|
||||||
## Action Items Checklist
|
|
||||||
|
|
||||||
### Immediate (Critical)
|
|
||||||
- [ ] Action item 1
|
|
||||||
- [ ] Action item 2
|
|
||||||
|
|
||||||
### Short-term (This Week)
|
|
||||||
- [ ] Action item 3
|
|
||||||
|
|
||||||
### Long-term (This Month)
|
|
||||||
- [ ] Action item 4
|
|
||||||
|
|
||||||
## Technical Details
|
|
||||||
|
|
||||||
### Environment
|
|
||||||
- URL Audited: https://example.com
|
|
||||||
- Audit Timestamp: YYYY-MM-DD HH:MM:SS
|
|
||||||
- Browser: Chromium (headless)
|
|
||||||
- Viewport: 1920x1080
|
|
||||||
|
|
||||||
### Raw Data
|
|
||||||
Full JSON report available at: `gtm_audit_report.json`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Appendix: Tag Destination Reference
|
|
||||||
|
|
||||||
| Tag Type | Network Pattern |
|
|
||||||
|----------|-----------------|
|
|
||||||
| GA4 | google-analytics.com/g/collect |
|
|
||||||
| UA (Legacy) | google-analytics.com/collect |
|
|
||||||
| Google Ads | googleads.g.doubleclick.net |
|
|
||||||
| Meta Pixel | facebook.com/tr |
|
|
||||||
| LinkedIn | px.ads.linkedin.com |
|
|
||||||
| TikTok | analytics.tiktok.com |
|
|
||||||
| Kakao | pixel.kakao.com |
|
|
||||||
| Naver | wcs.naver.com |
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
|||||||
playwright>=1.40.0
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# GTM Audit Tool Setup Script
|
|
||||||
|
|
||||||
echo "🔧 Setting up GTM Audit Tool..."
|
|
||||||
|
|
||||||
# Check Python
|
|
||||||
if ! command -v python3 &> /dev/null; then
|
|
||||||
echo "❌ Python 3 is required but not installed."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Python 3 found"
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
echo "📦 Installing Python dependencies..."
|
|
||||||
pip install -r requirements.txt
|
|
||||||
|
|
||||||
# Install Playwright browsers
|
|
||||||
echo "🌐 Installing Playwright browsers..."
|
|
||||||
playwright install chromium
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "✅ Setup complete!"
|
|
||||||
echo ""
|
|
||||||
echo "Usage:"
|
|
||||||
echo " python gtm_audit.py --url 'https://example.com' --journey full"
|
|
||||||
echo ""
|
|
||||||
echo "For Claude Code:"
|
|
||||||
echo " claude"
|
|
||||||
echo " > Run a GTM audit on https://example.com"
|
|
||||||
@@ -1,685 +0,0 @@
|
|||||||
{
|
|
||||||
"audit_metadata": {
|
|
||||||
"url": "https://josunhotel.com/resve/dining/step0.do",
|
|
||||||
"timestamp": "2025-12-20T23:27:54.071984",
|
|
||||||
"expected_container": null
|
|
||||||
},
|
|
||||||
"container_status": {
|
|
||||||
"installed": true,
|
|
||||||
"containers": [
|
|
||||||
"GTM-NP6NJMP"
|
|
||||||
],
|
|
||||||
"position": "head",
|
|
||||||
"noscript_present": true,
|
|
||||||
"datalayer_initialized": true,
|
|
||||||
"datalayer_init_before_gtm": false,
|
|
||||||
"issues": []
|
|
||||||
},
|
|
||||||
"datalayer_analysis": {
|
|
||||||
"events": [
|
|
||||||
{
|
|
||||||
"index": 0,
|
|
||||||
"event": "gtm.js",
|
|
||||||
"has_ecommerce": false,
|
|
||||||
"params": [
|
|
||||||
"gtm.start",
|
|
||||||
"event",
|
|
||||||
"gtm.uniqueEventId"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index": 1,
|
|
||||||
"event": "gtm.dom",
|
|
||||||
"has_ecommerce": false,
|
|
||||||
"params": [
|
|
||||||
"event",
|
|
||||||
"gtm.uniqueEventId"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index": 2,
|
|
||||||
"event": "gtm.load",
|
|
||||||
"has_ecommerce": false,
|
|
||||||
"params": [
|
|
||||||
"event",
|
|
||||||
"gtm.uniqueEventId"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index": 3,
|
|
||||||
"event": "gtm.scrollDepth",
|
|
||||||
"has_ecommerce": false,
|
|
||||||
"params": [
|
|
||||||
"event",
|
|
||||||
"gtm.scrollThreshold",
|
|
||||||
"gtm.scrollUnits",
|
|
||||||
"gtm.scrollDirection",
|
|
||||||
"gtm.triggers",
|
|
||||||
"gtm.uniqueEventId"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"validation_issues": [],
|
|
||||||
"sequence_issues": []
|
|
||||||
},
|
|
||||||
"form_analysis": {
|
|
||||||
"forms_found": [
|
|
||||||
{
|
|
||||||
"index": 0,
|
|
||||||
"id": "form",
|
|
||||||
"name": "form",
|
|
||||||
"action": "https://josunhotel.com/resve/dining/step0.do",
|
|
||||||
"method": "get",
|
|
||||||
"className": null,
|
|
||||||
"fieldCount": 2,
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"type": "hidden",
|
|
||||||
"name": "searchSysCode",
|
|
||||||
"id": "selectedSysCode",
|
|
||||||
"required": false,
|
|
||||||
"placeholder": null,
|
|
||||||
"validation": null,
|
|
||||||
"maxLength": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "hidden",
|
|
||||||
"name": "diningCode",
|
|
||||||
"id": "selectedDiningCode",
|
|
||||||
"required": false,
|
|
||||||
"placeholder": null,
|
|
||||||
"validation": null,
|
|
||||||
"maxLength": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"hasSubmitButton": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index": 1,
|
|
||||||
"id": "loginForm",
|
|
||||||
"name": "loginForm",
|
|
||||||
"action": "https://josunhotel.com/resve/dining/step0.do",
|
|
||||||
"method": "get",
|
|
||||||
"className": null,
|
|
||||||
"fieldCount": 1,
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"type": "hidden",
|
|
||||||
"name": "nextURL",
|
|
||||||
"id": "nextURL",
|
|
||||||
"required": false,
|
|
||||||
"placeholder": null,
|
|
||||||
"validation": null,
|
|
||||||
"maxLength": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"hasSubmitButton": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index": 2,
|
|
||||||
"id": "diningMenuPopForm",
|
|
||||||
"name": "diningMenuPopForm",
|
|
||||||
"action": "https://josunhotel.com/resve/dining/step0.do",
|
|
||||||
"method": "get",
|
|
||||||
"className": null,
|
|
||||||
"fieldCount": 4,
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"type": "hidden",
|
|
||||||
"name": "lclasCode",
|
|
||||||
"id": "lclasCode",
|
|
||||||
"required": false,
|
|
||||||
"placeholder": null,
|
|
||||||
"validation": null,
|
|
||||||
"maxLength": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "hidden",
|
|
||||||
"name": "searchSysCode",
|
|
||||||
"id": "menuPopSysCode",
|
|
||||||
"required": false,
|
|
||||||
"placeholder": null,
|
|
||||||
"validation": null,
|
|
||||||
"maxLength": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "hidden",
|
|
||||||
"name": "diningCode",
|
|
||||||
"id": "menuPopDiningCode",
|
|
||||||
"required": false,
|
|
||||||
"placeholder": null,
|
|
||||||
"validation": null,
|
|
||||||
"maxLength": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "hidden",
|
|
||||||
"name": "diningNm",
|
|
||||||
"id": "popDiningNm",
|
|
||||||
"required": false,
|
|
||||||
"placeholder": null,
|
|
||||||
"validation": null,
|
|
||||||
"maxLength": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"hasSubmitButton": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tracking_issues": [
|
|
||||||
{
|
|
||||||
"type": "form_no_submit",
|
|
||||||
"form_index": 0,
|
|
||||||
"message": "Form has no submit button - may use JS submission",
|
|
||||||
"recommendation": "Verify form submission triggers dataLayer push"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "form_no_submit",
|
|
||||||
"form_index": 1,
|
|
||||||
"message": "Form has no submit button - may use JS submission",
|
|
||||||
"recommendation": "Verify form submission triggers dataLayer push"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "form_no_submit",
|
|
||||||
"form_index": 2,
|
|
||||||
"message": "Form has no submit button - may use JS submission",
|
|
||||||
"recommendation": "Verify form submission triggers dataLayer push"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"events_status": {
|
|
||||||
"found": [],
|
|
||||||
"missing": [
|
|
||||||
"form_start",
|
|
||||||
"form_submit",
|
|
||||||
"generate_lead"
|
|
||||||
],
|
|
||||||
"recommendation": "Consider implementing: form_start, form_submit, generate_lead"
|
|
||||||
},
|
|
||||||
"interactions": [
|
|
||||||
{
|
|
||||||
"action": "focus",
|
|
||||||
"field": "searchSysCode",
|
|
||||||
"timestamp": "2025-12-20T23:28:02.063963"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"action": "blur",
|
|
||||||
"field": "searchSysCode",
|
|
||||||
"timestamp": "2025-12-20T23:28:02.277645"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"action": "focus",
|
|
||||||
"field": "diningCode",
|
|
||||||
"timestamp": "2025-12-20T23:28:02.284360"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"action": "blur",
|
|
||||||
"field": "diningCode",
|
|
||||||
"timestamp": "2025-12-20T23:28:02.496949"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"checkout_analysis": {
|
|
||||||
"elements_found": {
|
|
||||||
"cart": [],
|
|
||||||
"checkout": [],
|
|
||||||
"addToCart": [],
|
|
||||||
"quantity": [],
|
|
||||||
"removeItem": [],
|
|
||||||
"promoCode": []
|
|
||||||
},
|
|
||||||
"events_status": {},
|
|
||||||
"flow_issues": []
|
|
||||||
},
|
|
||||||
"network_requests": [
|
|
||||||
{
|
|
||||||
"destination": "Meta Pixel",
|
|
||||||
"url": "https://connect.facebook.net/en_US/fbevents.js",
|
|
||||||
"method": "GET",
|
|
||||||
"params": {},
|
|
||||||
"timestamp": "2025-12-20T23:27:55.520388"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"destination": "Meta Pixel",
|
|
||||||
"url": "https://connect.facebook.net/signals/config/538814301070436?v=2.9.248&r=stable&domain=josunhotel.com&hme=17590b9a2e1b26755cdc9ecb401f9f46bca979d3ccce95d786db0936167af731&ex_m=94%2C156%2C134%2C20%2C67%",
|
|
||||||
"method": "GET",
|
|
||||||
"params": {
|
|
||||||
"v": "2.9.248",
|
|
||||||
"r": "stable",
|
|
||||||
"domain": "josunhotel.com",
|
|
||||||
"hme": "17590b9a2e1b26755cdc9ecb401f9f46bca979d3ccce95d786db0936167af731",
|
|
||||||
"ex_m": "94,156,134,20,67,68,127,63,43,128,72,62,10,141,80,15,93,28,122,115,70,73,121,138,102,143,7,3,4,6,5,2,81,91,144,224,167,57,226,227,50,183,27,69,232,231,170,30,56,9,59,87,88,89,95,118,29,26,120,117,116,135,71,137,136,45,55,111,14,140,40,213,215,177,23,24,25,17,18,39,35,37,36,76,82,86,100,126,129,41,101,21,19,107,64,33,131,130,132,123,22,32,54,99,139,65,16,133,104,31,193,163,284,211,154,196,189,164,97,119,75,109,49,44,103,42,108,114,53,60,113,48,51,47,90,142,0,112,13,110,11,1,52,83,58,61,106,79,78,145,146,84,85,8,92,46,124,77,74,66,105,96,38,125,34,98,12,147"
|
|
||||||
},
|
|
||||||
"timestamp": "2025-12-20T23:27:55.567831"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"destination": "Meta Pixel",
|
|
||||||
"url": "https://www.facebook.com/tr/?id=538814301070436&ev=PageView&dl=https%3A%2F%2Fjosunhotel.com%2Fresve%2Fdining%2Fstep0.do&rl=&if=false&ts=1766240875594&sw=1920&sh=1080&v=2.9.248&r=stable&ec=0&o=4126&fbp",
|
|
||||||
"method": "GET",
|
|
||||||
"params": {
|
|
||||||
"id": "538814301070436",
|
|
||||||
"ev": "PageView",
|
|
||||||
"dl": "https://josunhotel.com/resve/dining/step0.do",
|
|
||||||
"if": "false",
|
|
||||||
"ts": "1766240875594",
|
|
||||||
"sw": "1920",
|
|
||||||
"sh": "1080",
|
|
||||||
"v": "2.9.248",
|
|
||||||
"r": "stable",
|
|
||||||
"ec": "0",
|
|
||||||
"o": "4126",
|
|
||||||
"fbp": "fb.1.1766240875591.938184183721303390",
|
|
||||||
"cs_est": "true",
|
|
||||||
"ler": "empty",
|
|
||||||
"plt": "403.89999985694885",
|
|
||||||
"it": "1766240875565",
|
|
||||||
"coo": "false",
|
|
||||||
"expv2[0]": "pl0",
|
|
||||||
"expv2[1]": "el2",
|
|
||||||
"expv2[2]": "bc1",
|
|
||||||
"expv2[3]": "mr2",
|
|
||||||
"expv2[4]": "im1",
|
|
||||||
"rqm": "GET"
|
|
||||||
},
|
|
||||||
"timestamp": "2025-12-20T23:27:55.597631"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"destination": "GA4",
|
|
||||||
"url": "https://analytics.google.com/g/collect?v=2&tid=G-H05VHCL3NE>m=45je5ca1v899119784z8836519946za20gzb836519946zd836519946&_p=1766240875171&_gaz=1&gcd=13l3l3l3l1l1&npa=0&dma=0&cid=702909924.1766240876&u",
|
|
||||||
"method": "POST",
|
|
||||||
"params": {
|
|
||||||
"v": "2",
|
|
||||||
"tid": "G-H05VHCL3NE",
|
|
||||||
"gtm": "45je5ca1v899119784z8836519946za20gzb836519946zd836519946",
|
|
||||||
"_p": "1766240875171",
|
|
||||||
"_gaz": "1",
|
|
||||||
"gcd": "13l3l3l3l1l1",
|
|
||||||
"npa": "0",
|
|
||||||
"dma": "0",
|
|
||||||
"cid": "702909924.1766240876",
|
|
||||||
"ul": "en-us",
|
|
||||||
"sr": "1920x1080",
|
|
||||||
"uaa": "x64",
|
|
||||||
"uab": "64",
|
|
||||||
"uafvl": "Chromium;136.0.7103.25|HeadlessChrome;136.0.7103.25|Not.A%2FBrand;99.0.0.0",
|
|
||||||
"uamb": "0",
|
|
||||||
"uap": "macOS",
|
|
||||||
"uapv": "10_15_7",
|
|
||||||
"uaw": "0",
|
|
||||||
"are": "1",
|
|
||||||
"frm": "0",
|
|
||||||
"pscdl": "noapi",
|
|
||||||
"_s": "1",
|
|
||||||
"tag_exp": "103116026~103200004~104527906~104528501~104684208~104684211~105391253~115583767~115938466~115938469~116184927~116184929~116251938~116251940",
|
|
||||||
"dp": "/resve/dining/step0.do",
|
|
||||||
"sid": "1766240875",
|
|
||||||
"sct": "1",
|
|
||||||
"seg": "0",
|
|
||||||
"dl": "https://josunhotel.com/resve/dining/step0.do",
|
|
||||||
"en": "page_view",
|
|
||||||
"_fv": "1",
|
|
||||||
"_nsi": "1",
|
|
||||||
"_ss": "1",
|
|
||||||
"ep.login_status": "비로그인",
|
|
||||||
"ep.user_lang": "ko",
|
|
||||||
"ep.contents_group_hotel": "조선호텔앤리조트",
|
|
||||||
"ep.contents_group_menu": "다이닝 이용",
|
|
||||||
"ep.contents_group_update": "다이닝 예약 프로세스",
|
|
||||||
"up.user_lang": "ko",
|
|
||||||
"up.login_status": "비로그인",
|
|
||||||
"tfd": "816"
|
|
||||||
},
|
|
||||||
"timestamp": "2025-12-20T23:27:55.700854"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"destination": "Google Ads",
|
|
||||||
"url": "https://googleads.g.doubleclick.net/pagead/viewthroughconversion/10876516957/?random=1766240875706&cv=11&fst=1766240875706&bg=ffffff&guid=ON&async=1&en=gtag.config>m=45be5ca1v887509085z8836519946za2",
|
|
||||||
"method": "GET",
|
|
||||||
"params": {
|
|
||||||
"random": "1766240875706",
|
|
||||||
"cv": "11",
|
|
||||||
"fst": "1766240875706",
|
|
||||||
"bg": "ffffff",
|
|
||||||
"guid": "ON",
|
|
||||||
"async": "1",
|
|
||||||
"en": "gtag.config",
|
|
||||||
"gtm": "45be5ca1v887509085z8836519946za20gzb836519946zd836519946xec",
|
|
||||||
"gcd": "13l3l3l3l1l1",
|
|
||||||
"dma": "0",
|
|
||||||
"tag_exp": "103116026~103200004~104527906~104528501~104684208~104684211~105391253~115583767~115616986~115938466~115938469~116184927~116184929~116251938~116251940",
|
|
||||||
"u_w": "1920",
|
|
||||||
"u_h": "1080",
|
|
||||||
"url": "https://josunhotel.com/resve/dining/step0.do",
|
|
||||||
"frm": "0",
|
|
||||||
"hn": "www.googleadservices.com",
|
|
||||||
"npa": "0",
|
|
||||||
"pscdl": "noapi",
|
|
||||||
"auid": "7778758.1766240876",
|
|
||||||
"uaa": "x64",
|
|
||||||
"uab": "64",
|
|
||||||
"uafvl": "Chromium;136.0.7103.25|HeadlessChrome;136.0.7103.25|Not.A%2FBrand;99.0.0.0",
|
|
||||||
"uamb": "0",
|
|
||||||
"uap": "macOS",
|
|
||||||
"uapv": "10_15_7",
|
|
||||||
"uaw": "0",
|
|
||||||
"data": "event=gtag.config",
|
|
||||||
"rfmt": "3",
|
|
||||||
"fmt": "4"
|
|
||||||
},
|
|
||||||
"timestamp": "2025-12-20T23:27:55.724178"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"destination": "Google Ads",
|
|
||||||
"url": "https://googleads.g.doubleclick.net/pagead/viewthroughconversion/10876516957/?random=1766240875722&cv=11&fst=1766240875722&bg=ffffff&guid=ON&async=1>m=45be5ca1v887509085z8836519946za20gzb836519946zd",
|
|
||||||
"method": "GET",
|
|
||||||
"params": {
|
|
||||||
"random": "1766240875722",
|
|
||||||
"cv": "11",
|
|
||||||
"fst": "1766240875722",
|
|
||||||
"bg": "ffffff",
|
|
||||||
"guid": "ON",
|
|
||||||
"async": "1",
|
|
||||||
"gtm": "45be5ca1v887509085z8836519946za20gzb836519946zd836519946xea",
|
|
||||||
"gcd": "13l3l3l3l1l1",
|
|
||||||
"dma": "0",
|
|
||||||
"tag_exp": "103116026~103200004~104527906~104528501~104684208~104684211~105391253~115583767~115616986~115938466~115938469~116184927~116184929~116251938~116251940",
|
|
||||||
"u_w": "1920",
|
|
||||||
"u_h": "1080",
|
|
||||||
"url": "https://josunhotel.com/resve/dining/step0.do",
|
|
||||||
"frm": "0",
|
|
||||||
"hn": "www.googleadservices.com",
|
|
||||||
"npa": "0",
|
|
||||||
"pscdl": "noapi",
|
|
||||||
"auid": "7778758.1766240876",
|
|
||||||
"uaa": "x64",
|
|
||||||
"uab": "64",
|
|
||||||
"uafvl": "Chromium;136.0.7103.25|HeadlessChrome;136.0.7103.25|Not.A%2FBrand;99.0.0.0",
|
|
||||||
"uamb": "0",
|
|
||||||
"uap": "macOS",
|
|
||||||
"uapv": "10_15_7",
|
|
||||||
"uaw": "0",
|
|
||||||
"_tu": "CA",
|
|
||||||
"rfmt": "3",
|
|
||||||
"fmt": "4"
|
|
||||||
},
|
|
||||||
"timestamp": "2025-12-20T23:27:55.724380"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"destination": "GA4",
|
|
||||||
"url": "https://analytics.google.com/g/collect?v=2&tid=G-TRL4XSZ1TD>m=45je5ca1v887683366z8836519946za20gzb836519946zd836519946&_p=1766240875171&em=tv.1~em.3UiOxkIGtQ4owYdw7yAOBB9qepQm5hB4t5octJYCI7g&_gaz=1&",
|
|
||||||
"method": "POST",
|
|
||||||
"params": {
|
|
||||||
"v": "2",
|
|
||||||
"tid": "G-TRL4XSZ1TD",
|
|
||||||
"gtm": "45je5ca1v887683366z8836519946za20gzb836519946zd836519946",
|
|
||||||
"_p": "1766240875171",
|
|
||||||
"em": "tv.1~em.3UiOxkIGtQ4owYdw7yAOBB9qepQm5hB4t5octJYCI7g",
|
|
||||||
"_gaz": "1",
|
|
||||||
"gcd": "13l3l3l3l1l1",
|
|
||||||
"npa": "0",
|
|
||||||
"dma": "0",
|
|
||||||
"cid": "702909924.1766240876",
|
|
||||||
"ecid": "599478978",
|
|
||||||
"ul": "en-us",
|
|
||||||
"sr": "1920x1080",
|
|
||||||
"ir": "1",
|
|
||||||
"uaa": "x64",
|
|
||||||
"uab": "64",
|
|
||||||
"uafvl": "Chromium;136.0.7103.25|HeadlessChrome;136.0.7103.25|Not.A%2FBrand;99.0.0.0",
|
|
||||||
"uamb": "0",
|
|
||||||
"uap": "macOS",
|
|
||||||
"uapv": "10_15_7",
|
|
||||||
"uaw": "0",
|
|
||||||
"are": "1",
|
|
||||||
"frm": "0",
|
|
||||||
"pscdl": "noapi",
|
|
||||||
"ec_mode": "a",
|
|
||||||
"_eu": "EA",
|
|
||||||
"_s": "1",
|
|
||||||
"tag_exp": "102015665~103116026~103200004~104527906~104528501~104684208~104684211~105391253~115583767~115616986~115938466~115938469~116184927~116184929~116251938~116251940",
|
|
||||||
"dp": "/resve/dining/step0.do",
|
|
||||||
"sid": "1766240875",
|
|
||||||
"sct": "1",
|
|
||||||
"seg": "0",
|
|
||||||
"dl": "https://josunhotel.com/resve/dining/step0.do",
|
|
||||||
"en": "page_view",
|
|
||||||
"_fv": "1",
|
|
||||||
"_ss": "1",
|
|
||||||
"ep.login_status": "비로그인",
|
|
||||||
"ep.user_lang": "ko",
|
|
||||||
"ep.contents_group_hotel": "조선호텔앤리조트",
|
|
||||||
"ep.contents_group_menu": "다이닝 이용",
|
|
||||||
"ep.contents_group_update": "다이닝 예약 프로세스",
|
|
||||||
"up.user_lang": "ko",
|
|
||||||
"up.login_status": "비로그인",
|
|
||||||
"tfd": "868"
|
|
||||||
},
|
|
||||||
"timestamp": "2025-12-20T23:27:55.742300"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"destination": "Google Ads",
|
|
||||||
"url": "https://www.google.com/pagead/1p-user-list/10876516957/?random=1766240875722&cv=11&fst=1766239200000&bg=ffffff&guid=ON&async=1>m=45be5ca1v887509085z8836519946za20gzb836519946zd836519946xea&gcd=13l3l",
|
|
||||||
"method": "GET",
|
|
||||||
"params": {
|
|
||||||
"random": [
|
|
||||||
"1766240875722",
|
|
||||||
"1725248437"
|
|
||||||
],
|
|
||||||
"cv": "11",
|
|
||||||
"fst": "1766239200000",
|
|
||||||
"bg": "ffffff",
|
|
||||||
"guid": "ON",
|
|
||||||
"async": "1",
|
|
||||||
"gtm": "45be5ca1v887509085z8836519946za20gzb836519946zd836519946xea",
|
|
||||||
"gcd": "13l3l3l3l1l1",
|
|
||||||
"dma": "0",
|
|
||||||
"tag_exp": "103116026~103200004~104527906~104528501~104684208~104684211~105391253~115583767~115616986~115938466~115938469~116184927~116184929~116251938~116251940",
|
|
||||||
"u_w": "1920",
|
|
||||||
"u_h": "1080",
|
|
||||||
"url": "https://josunhotel.com/resve/dining/step0.do",
|
|
||||||
"frm": "0",
|
|
||||||
"hn": "www.googleadservices.com",
|
|
||||||
"npa": "0",
|
|
||||||
"pscdl": "noapi",
|
|
||||||
"auid": "7778758.1766240876",
|
|
||||||
"uaa": "x64",
|
|
||||||
"uab": "64",
|
|
||||||
"uafvl": "Chromium;136.0.7103.25|HeadlessChrome;136.0.7103.25|Not.A%2FBrand;99.0.0.0",
|
|
||||||
"uamb": "0",
|
|
||||||
"uap": "macOS",
|
|
||||||
"uapv": "10_15_7",
|
|
||||||
"uaw": "0",
|
|
||||||
"_tu": "CA",
|
|
||||||
"rfmt": "3",
|
|
||||||
"fmt": "3",
|
|
||||||
"is_vtc": "1",
|
|
||||||
"cid": "CAQSfwDCSxrROzP7e5XZEQS8k7I9UCNrhQnG5V-tD4ZKQa_7FtJSznqwNhHyDNj7BO_ZAQ0ZmiPlxWqmbyGxMvHSi61fZhkyzwsqEi7B9tTXs6sacAba88_-qgv_8Rgn4jQGuJL6VEJJrTfyPEzvb8DkpSBnvoX3GsuNT06ie6uSVWc",
|
|
||||||
"rmt_tld": "0",
|
|
||||||
"ipr": "y"
|
|
||||||
},
|
|
||||||
"timestamp": "2025-12-20T23:27:55.988316"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"destination": "Google Ads",
|
|
||||||
"url": "https://www.google.com/pagead/1p-user-list/10876516957/?random=1766240875706&cv=11&fst=1766239200000&bg=ffffff&guid=ON&async=1&en=gtag.config>m=45be5ca1v887509085z8836519946za20gzb836519946zd8365199",
|
|
||||||
"method": "GET",
|
|
||||||
"params": {
|
|
||||||
"random": [
|
|
||||||
"1766240875706",
|
|
||||||
"47137349"
|
|
||||||
],
|
|
||||||
"cv": "11",
|
|
||||||
"fst": "1766239200000",
|
|
||||||
"bg": "ffffff",
|
|
||||||
"guid": "ON",
|
|
||||||
"async": "1",
|
|
||||||
"en": "gtag.config",
|
|
||||||
"gtm": "45be5ca1v887509085z8836519946za20gzb836519946zd836519946xec",
|
|
||||||
"gcd": "13l3l3l3l1l1",
|
|
||||||
"dma": "0",
|
|
||||||
"tag_exp": "103116026~103200004~104527906~104528501~104684208~104684211~105391253~115583767~115616986~115938466~115938469~116184927~116184929~116251938~116251940",
|
|
||||||
"u_w": "1920",
|
|
||||||
"u_h": "1080",
|
|
||||||
"url": "https://josunhotel.com/resve/dining/step0.do",
|
|
||||||
"frm": "0",
|
|
||||||
"hn": "www.googleadservices.com",
|
|
||||||
"npa": "0",
|
|
||||||
"pscdl": "noapi",
|
|
||||||
"auid": "7778758.1766240876",
|
|
||||||
"uaa": "x64",
|
|
||||||
"uab": "64",
|
|
||||||
"uafvl": "Chromium;136.0.7103.25|HeadlessChrome;136.0.7103.25|Not.A%2FBrand;99.0.0.0",
|
|
||||||
"uamb": "0",
|
|
||||||
"uap": "macOS",
|
|
||||||
"uapv": "10_15_7",
|
|
||||||
"uaw": "0",
|
|
||||||
"data": "event=gtag.config",
|
|
||||||
"rfmt": "3",
|
|
||||||
"fmt": "3",
|
|
||||||
"is_vtc": "1",
|
|
||||||
"cid": "CAQSfwDCSxrRlXV2juBCOX2pHU5qySObf1Ig-AD_NFppjlwlkvd1cQpXbh1i_ciiVUQiaEEtKY-q8RxtPsLk-6nSWigi7Rpe09oM62SpgggyFvUyqtM2ShCyr_w5AaTOI3665_Bn3q954YNmzAevWsWo3YNoUYN6S0r2iZE7jyFuHWQ",
|
|
||||||
"rmt_tld": "0",
|
|
||||||
"ipr": "y"
|
|
||||||
},
|
|
||||||
"timestamp": "2025-12-20T23:27:55.990657"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"destination": "GA4",
|
|
||||||
"url": "https://analytics.google.com/g/collect?v=2&tid=G-H05VHCL3NE>m=45je5ca1v899119784za20gzb836519946zd836519946&_p=1766240875171&gcd=13l3l3l3l1l1&npa=0&dma=0&cid=702909924.1766240876&ul=en-us&sr=1920x10",
|
|
||||||
"method": "POST",
|
|
||||||
"params": {
|
|
||||||
"v": "2",
|
|
||||||
"tid": "G-H05VHCL3NE",
|
|
||||||
"gtm": "45je5ca1v899119784za20gzb836519946zd836519946",
|
|
||||||
"_p": "1766240875171",
|
|
||||||
"gcd": "13l3l3l3l1l1",
|
|
||||||
"npa": "0",
|
|
||||||
"dma": "0",
|
|
||||||
"cid": "702909924.1766240876",
|
|
||||||
"ul": "en-us",
|
|
||||||
"sr": "1920x1080",
|
|
||||||
"uaa": "x64",
|
|
||||||
"uab": "64",
|
|
||||||
"uafvl": "Chromium;136.0.7103.25|HeadlessChrome;136.0.7103.25|Not.A%2FBrand;99.0.0.0",
|
|
||||||
"uamb": "0",
|
|
||||||
"uap": "macOS",
|
|
||||||
"uapv": "10_15_7",
|
|
||||||
"uaw": "0",
|
|
||||||
"are": "1",
|
|
||||||
"frm": "0",
|
|
||||||
"pscdl": "noapi",
|
|
||||||
"_eu": "AEAAAAQ",
|
|
||||||
"_s": "2",
|
|
||||||
"tag_exp": "103116026~103200004~104527906~104528501~104684208~104684211~105391253~115583767~115938466~115938469~116184927~116184929~116251938~116251940",
|
|
||||||
"dp": "/resve/dining/step0.do",
|
|
||||||
"sid": "1766240875",
|
|
||||||
"sct": "1",
|
|
||||||
"seg": "0",
|
|
||||||
"dl": "https://josunhotel.com/resve/dining/step0.do",
|
|
||||||
"_tu": "CA",
|
|
||||||
"en": "scroll",
|
|
||||||
"ep.login_status": "비로그인",
|
|
||||||
"ep.user_lang": "ko",
|
|
||||||
"ep.contents_group_hotel": "조선호텔앤리조트",
|
|
||||||
"ep.contents_group_menu": "다이닝 이용",
|
|
||||||
"ep.contents_group_update": "다이닝 예약 프로세스",
|
|
||||||
"epn.percent_scrolled": "90",
|
|
||||||
"_et": "3343",
|
|
||||||
"tfd": "9162"
|
|
||||||
},
|
|
||||||
"timestamp": "2025-12-20T23:28:04.037363"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"destination": "GA4",
|
|
||||||
"url": "https://analytics.google.com/g/collect?v=2&tid=G-TRL4XSZ1TD>m=45je5ca1v887683366za20gzb836519946zd836519946&_p=1766240875171&gcd=13l3l3l3l1l1&npa=0&dma=0&cid=702909924.1766240876&ecid=599478978&ul=e",
|
|
||||||
"method": "POST",
|
|
||||||
"params": {
|
|
||||||
"v": "2",
|
|
||||||
"tid": "G-TRL4XSZ1TD",
|
|
||||||
"gtm": "45je5ca1v887683366za20gzb836519946zd836519946",
|
|
||||||
"_p": "1766240875171",
|
|
||||||
"gcd": "13l3l3l3l1l1",
|
|
||||||
"npa": "0",
|
|
||||||
"dma": "0",
|
|
||||||
"cid": "702909924.1766240876",
|
|
||||||
"ecid": "599478978",
|
|
||||||
"ul": "en-us",
|
|
||||||
"sr": "1920x1080",
|
|
||||||
"ir": "1",
|
|
||||||
"uaa": "x64",
|
|
||||||
"uab": "64",
|
|
||||||
"uafvl": "Chromium;136.0.7103.25|HeadlessChrome;136.0.7103.25|Not.A%2FBrand;99.0.0.0",
|
|
||||||
"uamb": "0",
|
|
||||||
"uap": "macOS",
|
|
||||||
"uapv": "10_15_7",
|
|
||||||
"uaw": "0",
|
|
||||||
"are": "1",
|
|
||||||
"frm": "0",
|
|
||||||
"pscdl": "noapi",
|
|
||||||
"_eu": "EEAAAAQ",
|
|
||||||
"_s": "2",
|
|
||||||
"tag_exp": "102015665~103116026~103200004~104527906~104528501~104684208~104684211~105391253~115583767~115616986~115938466~115938469~116184927~116184929~116251938~116251940",
|
|
||||||
"dp": "/resve/dining/step0.do",
|
|
||||||
"sid": "1766240875",
|
|
||||||
"sct": "1",
|
|
||||||
"seg": "0",
|
|
||||||
"dl": "https://josunhotel.com/resve/dining/step0.do",
|
|
||||||
"_tu": "CA",
|
|
||||||
"en": "scroll",
|
|
||||||
"ep.login_status": "비로그인",
|
|
||||||
"ep.user_lang": "ko",
|
|
||||||
"ep.contents_group_hotel": "조선호텔앤리조트",
|
|
||||||
"ep.contents_group_menu": "다이닝 이용",
|
|
||||||
"ep.contents_group_update": "다이닝 예약 프로세스",
|
|
||||||
"epn.percent_scrolled": "90",
|
|
||||||
"_et": "3298",
|
|
||||||
"tfd": "9166"
|
|
||||||
},
|
|
||||||
"timestamp": "2025-12-20T23:28:04.040013"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tags_fired": [
|
|
||||||
"GA4",
|
|
||||||
"Google Ads",
|
|
||||||
"Meta Pixel"
|
|
||||||
],
|
|
||||||
"issues": [
|
|
||||||
{
|
|
||||||
"severity": "warning",
|
|
||||||
"type": "datalayer_order",
|
|
||||||
"message": "dataLayer should be initialized before GTM script"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"recommendations": [
|
|
||||||
{
|
|
||||||
"priority": "medium",
|
|
||||||
"action": "Initialize dataLayer before GTM",
|
|
||||||
"details": "Add 'window.dataLayer = window.dataLayer || [];' before GTM"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"priority": "medium",
|
|
||||||
"action": "Implement form tracking events",
|
|
||||||
"details": "Missing events: form_start, form_submit, generate_lead"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"checklist": {
|
|
||||||
"container_health": {
|
|
||||||
"gtm_installed": true,
|
|
||||||
"correct_container": true,
|
|
||||||
"no_duplicates": true,
|
|
||||||
"correct_position": true,
|
|
||||||
"datalayer_init_order": false
|
|
||||||
},
|
|
||||||
"datalayer_quality": {
|
|
||||||
"initialized": true,
|
|
||||||
"events_present": true,
|
|
||||||
"no_validation_errors": true,
|
|
||||||
"correct_sequence": true
|
|
||||||
},
|
|
||||||
"form_tracking": {
|
|
||||||
"forms_identifiable": true,
|
|
||||||
"form_events_present": false
|
|
||||||
},
|
|
||||||
"tag_firing": {
|
|
||||||
"ga4_active": true,
|
|
||||||
"requests_captured": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
# GTM Guardian
|
|
||||||
|
|
||||||
Google Tag Manager 태깅 전략 수립부터 구현, 유지보수까지 7단계 워크플로우를 지원하는 SMART Tool.
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
GTM Guardian은 GTM 태깅의 전체 라이프사이클을 체계적으로 관리합니다:
|
|
||||||
|
|
||||||
| Phase | Name | Description |
|
|
||||||
|-------|------|-------------|
|
|
||||||
| 1 | Web/App Analysis | DOM 분석, 태깅 가능 요소 식별 |
|
|
||||||
| 2 | User Behaviour & KPI | 사용자 여정 분석, KPI 정의 |
|
|
||||||
| 3 | Tagging Plan | 맞춤 이벤트, 파라미터 설계 |
|
|
||||||
| 4 | Event Taxonomy | 이벤트 택소노미 시트 구조화 |
|
|
||||||
| 5 | Implementation Guide | 구현 순서, 개발자 가이드 |
|
|
||||||
| 6 | Progressive Audit | 주기적 진단 및 업데이트 |
|
|
||||||
| 7 | Lookup App | 이벤트 조회 웹앱 |
|
|
||||||
|
|
||||||
## Dual-Platform Structure
|
|
||||||
|
|
||||||
이 스킬은 Claude Desktop과 Claude Code 양쪽에서 사용 가능합니다:
|
|
||||||
|
|
||||||
```
|
|
||||||
62-gtm-guardian/
|
|
||||||
├── desktop/ # Claude Desktop 버전
|
|
||||||
│ ├── SKILL.md # MCP 기반 워크플로우 (Phase 1-5)
|
|
||||||
│ ├── references/ # 분석/설계 가이드
|
|
||||||
│ └── templates/ # 태깅 계획서, 택소노미 템플릿
|
|
||||||
│
|
|
||||||
├── code/ # Claude Code 버전
|
|
||||||
│ ├── CLAUDE.md # 자동화 및 유지보수 (Phase 6-7)
|
|
||||||
│ ├── scripts/ # GTM Toolkit 연계
|
|
||||||
│ └── references/ # 감사/앱 가이드
|
|
||||||
│
|
|
||||||
└── README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
### Platform 역할 분담
|
|
||||||
|
|
||||||
| Platform | Phases | Focus |
|
|
||||||
|----------|--------|-------|
|
|
||||||
| **Desktop** | 1-5 | 분석, 설계, 문서 작성, Browser 분석, Notion 연동 |
|
|
||||||
| **Code** | 6-7 | GTM Toolkit 연계, Python 스크립트, API 자동화 |
|
|
||||||
|
|
||||||
## Quick Start
|
|
||||||
|
|
||||||
### Claude Desktop
|
|
||||||
1. `desktop/SKILL.md`를 Claude Desktop 설정에 추가
|
|
||||||
2. "GTM 태깅 계획 작성해줘" 등으로 시작
|
|
||||||
3. Phase 1-5 워크플로우 자동 진행
|
|
||||||
|
|
||||||
### Claude Code
|
|
||||||
1. `code/CLAUDE.md` 디렉토리에서 작업
|
|
||||||
2. D.intel GTM Toolkit 클론
|
|
||||||
3. Phase 6-7 자동화 작업 수행
|
|
||||||
|
|
||||||
## Key Features
|
|
||||||
|
|
||||||
### DataLayer & Events
|
|
||||||
- GA4 권장 이벤트 기반 스키마
|
|
||||||
- GA4, Meta, Kakao, Google Ads 플랫폼 매핑
|
|
||||||
- 일관된 네이밍 규칙
|
|
||||||
|
|
||||||
### Server-side GTM
|
|
||||||
- GCP Cloud Run, Stape.io, Google Tag Gateway 옵션
|
|
||||||
- 1st-party 쿠키, Privacy 강화
|
|
||||||
|
|
||||||
### Automation
|
|
||||||
- D.intelligence GTM Toolkit 연계
|
|
||||||
- Container 분석, 버전 비교, 미사용 요소 탐지
|
|
||||||
- Notion 자동 저장
|
|
||||||
|
|
||||||
## Site Type Support
|
|
||||||
|
|
||||||
| Site Type | Key Events |
|
|
||||||
|-----------|------------|
|
|
||||||
| E-commerce | view_item, add_to_cart, purchase |
|
|
||||||
| Lead Gen | generate_lead, form_submit |
|
|
||||||
| SaaS | sign_up, subscription_* |
|
|
||||||
| Media | article_view, scroll, video_* |
|
|
||||||
| B2B | demo_request, pricing_view |
|
|
||||||
|
|
||||||
## Related Resources
|
|
||||||
|
|
||||||
- [D.intelligence GTM Toolkit](https://github.com/ourdigital/dintel-gtm-agent)
|
|
||||||
- [GTM Knowledge Base (Notion)](https://www.notion.so/dintelligence/2cf581e58a1e80c8b358f1625356e931)
|
|
||||||
|
|
||||||
## Triggers
|
|
||||||
|
|
||||||
이 스킬은 다음 키워드에 반응합니다:
|
|
||||||
|
|
||||||
- GTM 태깅 계획, Tagging Plan 작성, 이벤트 설계
|
|
||||||
- DataLayer 스키마 설계, dataLayer 구현 가이드
|
|
||||||
- 사용자 행동 분석, User Behaviour Modeling, KPI 정의
|
|
||||||
- Event Taxonomy, 이벤트 택소노미, 이벤트 명명 규칙
|
|
||||||
- GTM 구현 가이드, 태그 설정 체크리스트
|
|
||||||
- Server-side GTM, sGTM, Stape
|
|
||||||
- GTM 감사, 진단, audit
|
|
||||||
@@ -1,168 +0,0 @@
|
|||||||
# GTM Guardian (Code)
|
|
||||||
|
|
||||||
GTM 태깅 라이프사이클의 자동화 및 유지보수 단계를 지원하는 Claude Code 스킬.
|
|
||||||
|
|
||||||
**Code 범위**: Phase 6-7 (Progressive Audit, Lookup App), GTM Toolkit 연계
|
|
||||||
|
|
||||||
> Desktop 스킬에서 Phase 1-5 (분석, 설계, 문서화)를 수행한 후 사용.
|
|
||||||
|
|
||||||
## Quick Commands
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# D.intelligence GTM Toolkit 클론
|
|
||||||
git clone https://github.com/ourdigital/dintel-gtm-agent.git
|
|
||||||
|
|
||||||
# GTM Container 분석
|
|
||||||
python analyze_container.py GTM-XXXXXX.json --output report.md
|
|
||||||
|
|
||||||
# 버전 비교
|
|
||||||
python diff_versions.py v1.json v2.json --output diff.md
|
|
||||||
|
|
||||||
# 미사용 요소 탐지
|
|
||||||
python find_unused.py container.json --type all
|
|
||||||
```
|
|
||||||
|
|
||||||
## Workflow Overview
|
|
||||||
|
|
||||||
| Phase | Name | Output | Tools |
|
|
||||||
|-------|------|--------|-------|
|
|
||||||
| 6 | Progressive Audit | 진단 리포트, 업데이트 | D.intel GTM Toolkit, Python |
|
|
||||||
| 7 | Lookup App | 이벤트 조회 앱 | Google Apps Script |
|
|
||||||
|
|
||||||
## Phase 6: Progressive Audit
|
|
||||||
|
|
||||||
### D.intelligence GTM Toolkit Integration
|
|
||||||
|
|
||||||
**Repository**: https://github.com/ourdigital/dintel-gtm-agent
|
|
||||||
|
|
||||||
### Capabilities
|
|
||||||
|
|
||||||
| Feature | Description | Use Case |
|
|
||||||
|---------|-------------|----------|
|
|
||||||
| Container Analysis | JSON 파싱, 구조 분석 | 컨테이너 리뷰 |
|
|
||||||
| Dependency Mapping | 태그↔트리거↔변수 관계 | 영향도 분석 |
|
|
||||||
| Version Diff | 버전 간 변경사항 비교 | 변경 추적 |
|
|
||||||
| Tag Validation | 발화 상태 자동 검증 | 정기 감사 |
|
|
||||||
|
|
||||||
### Audit Workflow
|
|
||||||
|
|
||||||
```
|
|
||||||
1. GTM Container Export
|
|
||||||
└── JSON 파일 다운로드 (GTM Admin > Container > Export)
|
|
||||||
|
|
||||||
2. D.intel Toolkit Analysis
|
|
||||||
├── python analyze_container.py container.json
|
|
||||||
├── Dependency graph 생성
|
|
||||||
└── Issue detection
|
|
||||||
|
|
||||||
3. Report Generation
|
|
||||||
└── Markdown/HTML 리포트
|
|
||||||
|
|
||||||
4. Notion 업로드
|
|
||||||
└── MCP 또는 수동 업로드
|
|
||||||
```
|
|
||||||
|
|
||||||
### Audit Schedule
|
|
||||||
|
|
||||||
| Frequency | Scope | Trigger |
|
|
||||||
|-----------|-------|---------|
|
|
||||||
| Weekly | Tag firing validation | 자동 스케줄 |
|
|
||||||
| Monthly | Full container review | 월간 리포트 |
|
|
||||||
| Quarterly | Architecture review | 분기 회의 |
|
|
||||||
| Ad-hoc | Issue investigation | 이슈 발생 시 |
|
|
||||||
|
|
||||||
## Phase 7: Lookup App
|
|
||||||
|
|
||||||
Google Apps Script 기반 Event Taxonomy 조회 앱 배포.
|
|
||||||
|
|
||||||
### Architecture
|
|
||||||
```
|
|
||||||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
||||||
│ Google Sheets │────▶│ Apps Script │────▶│ Web App │
|
|
||||||
│ (Taxonomy DB) │ │ (Backend) │ │ (Frontend) │
|
|
||||||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### Quick Setup
|
|
||||||
1. Google Sheets에서 Extensions > Apps Script
|
|
||||||
2. `references/phase7-lookup-app.md` 코드 참조
|
|
||||||
3. Deploy > New deployment > Web app
|
|
||||||
|
|
||||||
## Key References
|
|
||||||
|
|
||||||
- [phase6-audit.md](references/phase6-audit.md) - 진단 워크플로우, 체크리스트
|
|
||||||
- [phase7-lookup-app.md](references/phase7-lookup-app.md) - Apps Script 코드, 배포 가이드
|
|
||||||
|
|
||||||
### Shared References
|
|
||||||
- [datalayer-schema.md](references/datalayer-schema.md) - DataLayer 스키마
|
|
||||||
- [platform-mapping.md](references/platform-mapping.md) - 플랫폼별 이벤트 매핑
|
|
||||||
- [naming-conventions.md](references/naming-conventions.md) - 네이밍 규칙
|
|
||||||
- [qa-checklist.md](references/qa-checklist.md) - QA 체크리스트
|
|
||||||
|
|
||||||
## Notion Output
|
|
||||||
|
|
||||||
**Database**: [GTM Knowledge Base](https://www.notion.so/dintelligence/2cf581e58a1e80c8b358f1625356e931)
|
|
||||||
|
|
||||||
### Report Properties
|
|
||||||
|
|
||||||
| Property | Type | Description |
|
|
||||||
|----------|------|-------------|
|
|
||||||
| Project | Title | 프로젝트명 |
|
|
||||||
| Audit Date | Date | 감사 일자 |
|
|
||||||
| Container ID | Rich Text | GTM-XXXXXX |
|
|
||||||
| Status | Select | Healthy / Needs Attention / Critical |
|
|
||||||
| Version | Number | 컨테이너 버전 |
|
|
||||||
| Issues Count | Number | 발견 이슈 수 |
|
|
||||||
|
|
||||||
### Language Guidelines
|
|
||||||
- 리포트 내용은 한국어로 작성
|
|
||||||
- 기술 용어는 영어 유지 (GTM, dataLayer, GA4 등)
|
|
||||||
- 코드와 URL은 변경 없이 유지
|
|
||||||
|
|
||||||
## Common Tasks
|
|
||||||
|
|
||||||
### Container 분석 실행
|
|
||||||
```bash
|
|
||||||
cd dintel-gtm-agent
|
|
||||||
python analyze_container.py /path/to/GTM-XXXXXX.json \
|
|
||||||
--output /path/to/report.md \
|
|
||||||
--format markdown
|
|
||||||
```
|
|
||||||
|
|
||||||
### 버전 비교
|
|
||||||
```bash
|
|
||||||
python diff_versions.py \
|
|
||||||
/path/to/container_v1.json \
|
|
||||||
/path/to/container_v2.json \
|
|
||||||
--output diff_report.md
|
|
||||||
```
|
|
||||||
|
|
||||||
### 미사용 요소 탐지
|
|
||||||
```bash
|
|
||||||
python find_unused.py /path/to/container.json \
|
|
||||||
--type all \
|
|
||||||
--output unused_elements.md
|
|
||||||
```
|
|
||||||
|
|
||||||
## Update Procedures
|
|
||||||
|
|
||||||
### Minor Update (태그 수정)
|
|
||||||
1. 변경 필요 태그 식별
|
|
||||||
2. GTM Preview 모드에서 수정
|
|
||||||
3. 테스트 완료
|
|
||||||
4. Publish with version note
|
|
||||||
5. Notion 문서 업데이트
|
|
||||||
|
|
||||||
### Major Update (신규 태그 추가)
|
|
||||||
1. Desktop 스킬로 Phase 3-4 문서 업데이트
|
|
||||||
2. DataLayer 요구사항 개발팀 전달
|
|
||||||
3. GTM 태그/트리거/변수 설정
|
|
||||||
4. QA 체크리스트 수행
|
|
||||||
5. 단계적 배포
|
|
||||||
|
|
||||||
## Coding Guidelines
|
|
||||||
|
|
||||||
GTM Toolkit 수정 시:
|
|
||||||
1. **Tag Destinations**: `TAG_DESTINATIONS` dict에 플랫폼 추가
|
|
||||||
2. **Event Validation**: `GA4_EVENT_REQUIREMENTS` dict에 요구사항 추가
|
|
||||||
3. **Korean Patterns**: 한국 결제 수단 (카카오페이, 네이버페이, 토스) 지원
|
|
||||||
@@ -1,193 +0,0 @@
|
|||||||
# DataLayer Schema Reference
|
|
||||||
|
|
||||||
GA4 권장 이벤트 기반 DataLayer 스키마 정의.
|
|
||||||
|
|
||||||
## Core Principles
|
|
||||||
|
|
||||||
1. GTM 스니펫 이전에 dataLayer 초기화
|
|
||||||
2. 이벤트 발생 시점에 push (사전 아님)
|
|
||||||
3. ecommerce 객체는 push 전 clear 필수
|
|
||||||
4. PII 데이터 직접 수집 금지
|
|
||||||
|
|
||||||
## Base Structure
|
|
||||||
|
|
||||||
### Page Load
|
|
||||||
```javascript
|
|
||||||
window.dataLayer = window.dataLayer || [];
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'page_data',
|
|
||||||
'page': {
|
|
||||||
'type': 'home|category|product|cart|checkout|thankyou|content|search',
|
|
||||||
'name': 'Page Name',
|
|
||||||
'category': 'Category/Subcategory',
|
|
||||||
'language': 'ko'
|
|
||||||
},
|
|
||||||
'user': {
|
|
||||||
'status': 'logged_in|logged_out',
|
|
||||||
'id': 'hashed_user_id', // SHA256, 로그인 시에만
|
|
||||||
'type': 'new|returning|member|guest',
|
|
||||||
'loginMethod': 'email|kakao|naver|google'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## E-commerce Events
|
|
||||||
|
|
||||||
### view_item
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'view_item',
|
|
||||||
'ecommerce': {
|
|
||||||
'currency': 'KRW',
|
|
||||||
'value': 29000,
|
|
||||||
'items': [{
|
|
||||||
'item_id': 'SKU_12345',
|
|
||||||
'item_name': 'Product Name',
|
|
||||||
'item_brand': 'Brand Name',
|
|
||||||
'item_category': 'Category',
|
|
||||||
'item_variant': 'Blue / Large',
|
|
||||||
'price': 29000,
|
|
||||||
'quantity': 1
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### add_to_cart
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'add_to_cart',
|
|
||||||
'ecommerce': {
|
|
||||||
'currency': 'KRW',
|
|
||||||
'value': 29000,
|
|
||||||
'items': [{
|
|
||||||
'item_id': 'SKU_12345',
|
|
||||||
'item_name': 'Product Name',
|
|
||||||
'price': 29000,
|
|
||||||
'quantity': 1
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### begin_checkout
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'begin_checkout',
|
|
||||||
'ecommerce': {
|
|
||||||
'currency': 'KRW',
|
|
||||||
'value': 58000,
|
|
||||||
'coupon': 'WELCOME10',
|
|
||||||
'items': [/* cart items */]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### purchase
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'purchase',
|
|
||||||
'ecommerce': {
|
|
||||||
'transaction_id': 'T_20250115_001',
|
|
||||||
'affiliation': 'Store Name',
|
|
||||||
'value': 53000,
|
|
||||||
'tax': 4818,
|
|
||||||
'shipping': 3000,
|
|
||||||
'currency': 'KRW',
|
|
||||||
'coupon': 'WELCOME10',
|
|
||||||
'items': [{
|
|
||||||
'item_id': 'SKU_12345',
|
|
||||||
'item_name': 'Product Name',
|
|
||||||
'price': 29000,
|
|
||||||
'quantity': 1
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Lead Gen Events
|
|
||||||
|
|
||||||
### generate_lead
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'generate_lead',
|
|
||||||
'currency': 'KRW',
|
|
||||||
'value': 50000,
|
|
||||||
'lead': {
|
|
||||||
'source': 'contact_form|landing_page',
|
|
||||||
'type': 'inquiry|quote_request'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### form_submit
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'form_submit',
|
|
||||||
'form': {
|
|
||||||
'id': 'contact_form',
|
|
||||||
'name': 'Contact Us Form',
|
|
||||||
'type': 'contact',
|
|
||||||
'success': true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Engagement Events
|
|
||||||
|
|
||||||
### login / sign_up
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'login', // or 'sign_up'
|
|
||||||
'method': 'email|kakao|naver|google'
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### search
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'search',
|
|
||||||
'search_term': 'user search query',
|
|
||||||
'search': {
|
|
||||||
'results_count': 42,
|
|
||||||
'category': 'product|content'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Item Object Reference
|
|
||||||
|
|
||||||
| Parameter | Type | Required | Description |
|
|
||||||
|-----------|------|----------|-------------|
|
|
||||||
| item_id | string | Yes | SKU |
|
|
||||||
| item_name | string | Yes | 상품명 |
|
|
||||||
| price | number | Yes | 단가 |
|
|
||||||
| quantity | number | Yes | 수량 |
|
|
||||||
| item_brand | string | No | 브랜드명 |
|
|
||||||
| item_category | string | No | 카테고리 |
|
|
||||||
| item_category2-5 | string | No | 하위 카테고리 |
|
|
||||||
| item_variant | string | No | 옵션 |
|
|
||||||
| coupon | string | No | 쿠폰 코드 |
|
|
||||||
| discount | number | No | 할인 금액 |
|
|
||||||
| index | number | No | 목록 위치 |
|
|
||||||
|
|
||||||
## Validation Rules
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// ✅ Correct
|
|
||||||
'price': 29000 // number
|
|
||||||
'quantity': 1 // number
|
|
||||||
'currency': 'KRW' // uppercase
|
|
||||||
|
|
||||||
// ❌ Wrong
|
|
||||||
'price': '29000' // string
|
|
||||||
'currency': 'krw' // lowercase
|
|
||||||
```
|
|
||||||
|
|
||||||
### Array Limits
|
|
||||||
- items[]: 최대 200개
|
|
||||||
- 초과 시 분할 전송
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
# GTM Naming Conventions
|
|
||||||
|
|
||||||
일관된 GTM 컨테이너 관리를 위한 네이밍 규칙.
|
|
||||||
|
|
||||||
## Tag Naming
|
|
||||||
|
|
||||||
### Pattern
|
|
||||||
```
|
|
||||||
[Platform] - [Type] - [Description]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
| Platform | Type | Description | Tag Name |
|
|
||||||
|----------|------|-------------|----------|
|
|
||||||
| GA4 | Config | Main | GA4 - Config - Main |
|
|
||||||
| GA4 | Event | purchase | GA4 - Event - purchase |
|
|
||||||
| GAds | Conversion | Purchase | GAds - Conversion - Purchase |
|
|
||||||
| Meta | Event | Purchase | Meta - Event - Purchase |
|
|
||||||
| Kakao | Event | purchase | Kakao - Event - purchase |
|
|
||||||
|
|
||||||
## Trigger Naming
|
|
||||||
|
|
||||||
### Pattern
|
|
||||||
```
|
|
||||||
[Type] - [Condition] - [Context]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Type Codes
|
|
||||||
| Code | Type | Example |
|
|
||||||
|------|------|---------|
|
|
||||||
| PV | Page View | PV - All Pages |
|
|
||||||
| DL | DataLayer Event | DL - purchase |
|
|
||||||
| Click | Click | Click - CTA Button |
|
|
||||||
| Form | Form Submit | Form - Contact |
|
|
||||||
| Scroll | Scroll Depth | Scroll - 75% |
|
|
||||||
| Vis | Element Visibility | Vis - Video Player |
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
```
|
|
||||||
PV - All Pages
|
|
||||||
PV - Thank You Page
|
|
||||||
DL - purchase
|
|
||||||
DL - add_to_cart
|
|
||||||
Click - CTA Button - Hero
|
|
||||||
Form - Contact Form
|
|
||||||
Scroll - 90%
|
|
||||||
```
|
|
||||||
|
|
||||||
## Variable Naming
|
|
||||||
|
|
||||||
### Pattern
|
|
||||||
```
|
|
||||||
[Type] - [Name/Path]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Type Codes
|
|
||||||
| Code | Type | Example |
|
|
||||||
|------|------|---------|
|
|
||||||
| DLV | DataLayer Variable | DLV - ecommerce.value |
|
|
||||||
| CJS | Custom JavaScript | CJS - Item IDs Array |
|
|
||||||
| Const | Constant | Const - GA4 Measurement ID |
|
|
||||||
| LT | Lookup Table | LT - Page Type Mapping |
|
|
||||||
| URL | URL Variable | URL - Path |
|
|
||||||
| DOM | DOM Element | DOM - Product Title |
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
```
|
|
||||||
DLV - event
|
|
||||||
DLV - ecommerce.transaction_id
|
|
||||||
DLV - ecommerce.items
|
|
||||||
CJS - Items for Meta
|
|
||||||
CJS - Formatted Price
|
|
||||||
Const - GA4 Measurement ID
|
|
||||||
Const - Meta Pixel ID
|
|
||||||
LT - Payment Method Mapping
|
|
||||||
```
|
|
||||||
|
|
||||||
## Folder Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
📁 01. Configuration
|
|
||||||
📁 02. GA4 Events
|
|
||||||
📁 03. Google Ads
|
|
||||||
📁 04. Meta Pixel
|
|
||||||
📁 05. Kakao Pixel
|
|
||||||
📁 06. Other Platforms
|
|
||||||
📁 07. Utilities
|
|
||||||
📁 99. Deprecated
|
|
||||||
```
|
|
||||||
|
|
||||||
## Built-in Variables to Enable
|
|
||||||
|
|
||||||
```
|
|
||||||
Pages: ✅ Page URL, Path, Hostname, Referrer
|
|
||||||
Utilities: ✅ Event, Container ID, Random Number
|
|
||||||
Clicks: ✅ Element, Classes, ID, URL, Text
|
|
||||||
Forms: ✅ Element, Classes, ID, URL, Text
|
|
||||||
History: ✅ New/Old History Fragment/State
|
|
||||||
Videos: ✅ All YouTube variables
|
|
||||||
Scrolling: ✅ Depth Threshold, Units, Direction
|
|
||||||
Visibility: ✅ Percent Visible, On-Screen Duration
|
|
||||||
```
|
|
||||||
|
|
||||||
## Anti-patterns
|
|
||||||
|
|
||||||
```
|
|
||||||
❌ Tag 1, New Tag, Test
|
|
||||||
❌ GA4 purchase event (일관성 없음)
|
|
||||||
❌ G4-E-Pch (과도한 약어)
|
|
||||||
❌ Very Long Tag Name for Purchase Complete Event (너무 김)
|
|
||||||
|
|
||||||
✅ GA4 - Event - purchase
|
|
||||||
✅ DL - purchase
|
|
||||||
✅ CJS - Items for Meta
|
|
||||||
```
|
|
||||||
|
|
||||||
## Version Notes
|
|
||||||
|
|
||||||
```
|
|
||||||
v[Major].[Minor] - [Description]
|
|
||||||
예: v12.1 - Added form_submit event
|
|
||||||
|
|
||||||
## Changes
|
|
||||||
- Added:
|
|
||||||
- Modified:
|
|
||||||
- Removed:
|
|
||||||
|
|
||||||
## Reason
|
|
||||||
[변경 이유]
|
|
||||||
```
|
|
||||||
@@ -1,215 +0,0 @@
|
|||||||
# Phase 6: Progressive Audit & Update
|
|
||||||
|
|
||||||
설정된 GTM Container에 대한 주기적 진단, 유효성 검증, 마이너 업데이트 및 태그 추가.
|
|
||||||
|
|
||||||
## Objectives
|
|
||||||
|
|
||||||
1. GTM 컨테이너 건강 상태 점검
|
|
||||||
2. 태그 발화 및 데이터 정합성 검증
|
|
||||||
3. 최신 요구사항 반영 업데이트
|
|
||||||
4. D.intelligence GTM Toolkit 연계 자동화
|
|
||||||
|
|
||||||
## Audit Schedule
|
|
||||||
|
|
||||||
| Frequency | Scope | Trigger |
|
|
||||||
|-----------|-------|---------|
|
|
||||||
| Weekly | Tag firing validation | 자동 스케줄 |
|
|
||||||
| Monthly | Full container review | 월간 리포트 |
|
|
||||||
| Quarterly | Architecture review | 분기 회의 |
|
|
||||||
| Ad-hoc | Issue investigation | 이슈 발생 시 |
|
|
||||||
|
|
||||||
## Audit Checklist
|
|
||||||
|
|
||||||
### 1. Container Health Check
|
|
||||||
- [ ] 버전 히스토리 확인 (최근 변경사항)
|
|
||||||
- [ ] 미사용 태그/트리거/변수 식별
|
|
||||||
- [ ] 명명 규칙 준수 여부
|
|
||||||
- [ ] 폴더 구조 정리 상태
|
|
||||||
|
|
||||||
### 2. Tag Firing Validation
|
|
||||||
- [ ] 모든 P1 태그 정상 발화
|
|
||||||
- [ ] 트리거 조건 정확성
|
|
||||||
- [ ] 변수 값 정확성
|
|
||||||
- [ ] 차단 트리거 작동
|
|
||||||
|
|
||||||
### 3. Data Quality
|
|
||||||
- [ ] GA4 Realtime 데이터 확인
|
|
||||||
- [ ] 전환 데이터 정합성
|
|
||||||
- [ ] 파라미터 값 검증
|
|
||||||
- [ ] 이상치 탐지
|
|
||||||
|
|
||||||
### 4. Platform Sync
|
|
||||||
- [ ] GA4 ↔ GTM 동기화
|
|
||||||
- [ ] Google Ads 전환 데이터
|
|
||||||
- [ ] Meta Events Manager 상태
|
|
||||||
- [ ] Kakao Pixel 상태
|
|
||||||
|
|
||||||
## D.intelligence GTM Toolkit Integration
|
|
||||||
|
|
||||||
### Repository
|
|
||||||
```
|
|
||||||
https://github.com/ourdigital/dintel-gtm-agent
|
|
||||||
```
|
|
||||||
|
|
||||||
### Capabilities
|
|
||||||
|
|
||||||
| Feature | Description | Use Case |
|
|
||||||
|---------|-------------|----------|
|
|
||||||
| Container Analysis | JSON 파싱, 구조 분석 | 컨테이너 리뷰 |
|
|
||||||
| Dependency Mapping | 태그↔트리거↔변수 관계 | 영향도 분석 |
|
|
||||||
| Version Diff | 버전 간 변경사항 비교 | 변경 추적 |
|
|
||||||
| Tag Validation | 발화 상태 자동 검증 | 정기 감사 |
|
|
||||||
|
|
||||||
### Integration Workflow
|
|
||||||
|
|
||||||
```
|
|
||||||
1. GTM Container Export
|
|
||||||
└── JSON 파일 다운로드
|
|
||||||
|
|
||||||
2. D.intel Toolkit Analysis
|
|
||||||
├── python analyze_container.py container.json
|
|
||||||
├── Dependency graph 생성
|
|
||||||
└── Issue detection
|
|
||||||
|
|
||||||
3. Report Generation
|
|
||||||
└── Markdown/HTML 리포트
|
|
||||||
|
|
||||||
4. GTM Guardian Update
|
|
||||||
└── Notion에 리포트 저장
|
|
||||||
```
|
|
||||||
|
|
||||||
### Sample Toolkit Commands
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Container 분석
|
|
||||||
python analyze_container.py GTM-XXXXXX.json --output report.md
|
|
||||||
|
|
||||||
# 버전 비교
|
|
||||||
python diff_versions.py v1.json v2.json --output diff.md
|
|
||||||
|
|
||||||
# 태그 검증
|
|
||||||
python validate_tags.py container.json --events events.csv
|
|
||||||
|
|
||||||
# 미사용 요소 탐지
|
|
||||||
python find_unused.py container.json --type all
|
|
||||||
```
|
|
||||||
|
|
||||||
## Audit Report Template
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# GTM Audit Report
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
- **Container**: GTM-XXXXXX
|
|
||||||
- **Audit Date**: YYYY-MM-DD
|
|
||||||
- **Version Reviewed**: XX
|
|
||||||
- **Overall Status**: ✅ Healthy / ⚠️ Needs Attention / ❌ Critical
|
|
||||||
|
|
||||||
## Findings
|
|
||||||
|
|
||||||
### ✅ Passing
|
|
||||||
- [항목]
|
|
||||||
|
|
||||||
### ⚠️ Warnings
|
|
||||||
| Issue | Impact | Recommendation |
|
|
||||||
|-------|--------|----------------|
|
|
||||||
|
|
||||||
### ❌ Critical
|
|
||||||
| Issue | Impact | Action Required |
|
|
||||||
|-------|--------|-----------------|
|
|
||||||
|
|
||||||
## Tag Firing Status
|
|
||||||
|
|
||||||
| Tag | Expected | Actual | Status |
|
|
||||||
|-----|----------|--------|--------|
|
|
||||||
| GA4 - Event - purchase | Thank You | Thank You | ✅ |
|
|
||||||
|
|
||||||
## Data Quality Check
|
|
||||||
|
|
||||||
| Metric | Expected | Actual | Variance |
|
|
||||||
|--------|----------|--------|----------|
|
|
||||||
| Daily Purchases | ~50 | 48 | -4% |
|
|
||||||
|
|
||||||
## Recommendations
|
|
||||||
1.
|
|
||||||
2.
|
|
||||||
|
|
||||||
## Next Steps
|
|
||||||
- [ ]
|
|
||||||
- [ ]
|
|
||||||
|
|
||||||
## Appendix
|
|
||||||
- Container JSON snapshot
|
|
||||||
- D.intel Toolkit output
|
|
||||||
```
|
|
||||||
|
|
||||||
## Update Procedures
|
|
||||||
|
|
||||||
### Minor Update (태그 수정)
|
|
||||||
```
|
|
||||||
1. 변경 필요 태그 식별
|
|
||||||
2. Preview 모드에서 수정
|
|
||||||
3. 테스트 완료
|
|
||||||
4. Publish with version note
|
|
||||||
5. Notion 문서 업데이트
|
|
||||||
```
|
|
||||||
|
|
||||||
### Major Update (신규 태그 추가)
|
|
||||||
```
|
|
||||||
1. Phase 3-4 문서 업데이트
|
|
||||||
2. DataLayer 요구사항 개발팀 전달
|
|
||||||
3. GTM 태그/트리거/변수 설정
|
|
||||||
4. QA 체크리스트 수행
|
|
||||||
5. 단계적 배포
|
|
||||||
6. Notion 문서 업데이트
|
|
||||||
```
|
|
||||||
|
|
||||||
### Emergency Fix
|
|
||||||
```
|
|
||||||
1. 이슈 원인 파악
|
|
||||||
2. 최소 변경으로 수정
|
|
||||||
3. Publish (emergency version note)
|
|
||||||
4. 근본 원인 분석
|
|
||||||
5. 영구 수정 계획
|
|
||||||
```
|
|
||||||
|
|
||||||
## Versioning Best Practices
|
|
||||||
|
|
||||||
### Version Naming
|
|
||||||
```
|
|
||||||
v[Major].[Minor] - [Description]
|
|
||||||
예: v12.1 - Added form_submit event
|
|
||||||
```
|
|
||||||
|
|
||||||
### Version Notes Template
|
|
||||||
```
|
|
||||||
## Changes
|
|
||||||
- Added: [새로 추가된 항목]
|
|
||||||
- Modified: [수정된 항목]
|
|
||||||
- Removed: [삭제된 항목]
|
|
||||||
|
|
||||||
## Reason
|
|
||||||
[변경 이유]
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
- [테스트 항목 및 결과]
|
|
||||||
|
|
||||||
## Rollback Plan
|
|
||||||
[롤백 필요 시 절차]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Monitoring Setup
|
|
||||||
|
|
||||||
### GA4 Alerts
|
|
||||||
- 일일 전환 수 급감 (>30%)
|
|
||||||
- 세션 수 급감 (>50%)
|
|
||||||
- 이벤트 수집 오류
|
|
||||||
|
|
||||||
### Custom Monitoring
|
|
||||||
- DataLayer 오류 로깅
|
|
||||||
- Tag Manager 오류 추적
|
|
||||||
- 서버 사이드 태그 상태 (sGTM 시)
|
|
||||||
|
|
||||||
## Next Phase
|
|
||||||
|
|
||||||
주기적 감사 완료 후 → Phase 7: Lookup App (필요 시)
|
|
||||||
@@ -1,283 +0,0 @@
|
|||||||
# Phase 7: Event Lookup & Parameter Library Web App
|
|
||||||
|
|
||||||
Google Apps Script를 활용한 Event Taxonomy Sheet 기반 업무 지원용 앱 배포.
|
|
||||||
|
|
||||||
## Objectives
|
|
||||||
|
|
||||||
1. Event Taxonomy 데이터 조회 앱
|
|
||||||
2. 실시간 파라미터 참조 도구
|
|
||||||
3. 비개발자용 Self-service 도구
|
|
||||||
4. 팀 간 일관된 이벤트 정보 공유
|
|
||||||
|
|
||||||
## App Architecture
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
||||||
│ Google Sheets │────▶│ Apps Script │────▶│ Web App │
|
|
||||||
│ (Taxonomy DB) │ │ (Backend) │ │ (Frontend) │
|
|
||||||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## Google Sheets Data Source
|
|
||||||
|
|
||||||
### Required Sheets
|
|
||||||
- Events Master
|
|
||||||
- Parameters Reference
|
|
||||||
- Custom Definitions
|
|
||||||
- Platform Mapping
|
|
||||||
|
|
||||||
### Column Requirements
|
|
||||||
→ Phase 4 참조: [phase4-taxonomy.md](phase4-taxonomy.md)
|
|
||||||
|
|
||||||
## Apps Script Setup
|
|
||||||
|
|
||||||
### 1. Project Creation
|
|
||||||
```
|
|
||||||
1. Google Sheets 열기
|
|
||||||
2. Extensions > Apps Script
|
|
||||||
3. 프로젝트 이름 설정
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Core Functions
|
|
||||||
|
|
||||||
#### Data Retrieval
|
|
||||||
```javascript
|
|
||||||
function getEventsData() {
|
|
||||||
const sheet = SpreadsheetApp.getActiveSpreadsheet()
|
|
||||||
.getSheetByName('Events Master');
|
|
||||||
const data = sheet.getDataRange().getValues();
|
|
||||||
const headers = data[0];
|
|
||||||
|
|
||||||
return data.slice(1).map(row => {
|
|
||||||
const obj = {};
|
|
||||||
headers.forEach((header, i) => {
|
|
||||||
obj[header] = row[i];
|
|
||||||
});
|
|
||||||
return obj;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getParametersData() {
|
|
||||||
const sheet = SpreadsheetApp.getActiveSpreadsheet()
|
|
||||||
.getSheetByName('Parameters Reference');
|
|
||||||
const data = sheet.getDataRange().getValues();
|
|
||||||
const headers = data[0];
|
|
||||||
|
|
||||||
return data.slice(1).map(row => {
|
|
||||||
const obj = {};
|
|
||||||
headers.forEach((header, i) => {
|
|
||||||
obj[header] = row[i];
|
|
||||||
});
|
|
||||||
return obj;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Search Function
|
|
||||||
```javascript
|
|
||||||
function searchEvents(query) {
|
|
||||||
const events = getEventsData();
|
|
||||||
const searchTerm = query.toLowerCase();
|
|
||||||
|
|
||||||
return events.filter(event =>
|
|
||||||
event.event_name.toLowerCase().includes(searchTerm) ||
|
|
||||||
event.event_category.toLowerCase().includes(searchTerm) ||
|
|
||||||
event.notes.toLowerCase().includes(searchTerm)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getEventDetails(eventName) {
|
|
||||||
const events = getEventsData();
|
|
||||||
const params = getParametersData();
|
|
||||||
|
|
||||||
const event = events.find(e => e.event_name === eventName);
|
|
||||||
if (!event) return null;
|
|
||||||
|
|
||||||
const eventParams = event.parameters.split(',').map(p => p.trim());
|
|
||||||
const paramDetails = params.filter(p =>
|
|
||||||
eventParams.includes(p.parameter_name)
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
event: event,
|
|
||||||
parameters: paramDetails
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Web App Handler
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
function doGet(e) {
|
|
||||||
return HtmlService.createHtmlOutputFromFile('index')
|
|
||||||
.setTitle('GTM Event Lookup')
|
|
||||||
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
|
|
||||||
}
|
|
||||||
|
|
||||||
function doPost(e) {
|
|
||||||
const action = e.parameter.action;
|
|
||||||
|
|
||||||
switch(action) {
|
|
||||||
case 'search':
|
|
||||||
return ContentService.createTextOutput(
|
|
||||||
JSON.stringify(searchEvents(e.parameter.query))
|
|
||||||
).setMimeType(ContentService.MimeType.JSON);
|
|
||||||
|
|
||||||
case 'details':
|
|
||||||
return ContentService.createTextOutput(
|
|
||||||
JSON.stringify(getEventDetails(e.parameter.eventName))
|
|
||||||
).setMimeType(ContentService.MimeType.JSON);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return ContentService.createTextOutput(
|
|
||||||
JSON.stringify({error: 'Invalid action'})
|
|
||||||
).setMimeType(ContentService.MimeType.JSON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. HTML Frontend (index.html)
|
|
||||||
|
|
||||||
```html
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<base target="_top">
|
|
||||||
<style>
|
|
||||||
body { font-family: 'Roboto', sans-serif; padding: 20px; max-width: 800px; margin: 0 auto; }
|
|
||||||
.search-box { width: 100%; padding: 12px; font-size: 16px; margin-bottom: 20px; }
|
|
||||||
.event-card { border: 1px solid #ddd; padding: 16px; margin: 10px 0; border-radius: 8px; }
|
|
||||||
.event-name { font-size: 18px; font-weight: bold; color: #1a73e8; }
|
|
||||||
.param-badge { background: #e8f0fe; color: #1967d2; padding: 4px 8px; border-radius: 4px; margin: 2px; display: inline-block; }
|
|
||||||
.category { color: #5f6368; font-size: 14px; }
|
|
||||||
.priority-p1 { border-left: 4px solid #ea4335; }
|
|
||||||
.priority-p2 { border-left: 4px solid #fbbc04; }
|
|
||||||
.priority-p3 { border-left: 4px solid #34a853; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>🏷️ GTM Event Lookup</h1>
|
|
||||||
<input type="text" class="search-box" id="searchInput" placeholder="이벤트명 또는 카테고리 검색...">
|
|
||||||
<div id="results"></div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
const searchInput = document.getElementById('searchInput');
|
|
||||||
const results = document.getElementById('results');
|
|
||||||
|
|
||||||
searchInput.addEventListener('input', debounce(function() {
|
|
||||||
const query = this.value;
|
|
||||||
if (query.length < 2) {
|
|
||||||
results.innerHTML = '';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
google.script.run
|
|
||||||
.withSuccessHandler(displayResults)
|
|
||||||
.searchEvents(query);
|
|
||||||
}, 300));
|
|
||||||
|
|
||||||
function displayResults(events) {
|
|
||||||
results.innerHTML = events.map(event => `
|
|
||||||
<div class="event-card priority-${event.priority.toLowerCase()}">
|
|
||||||
<div class="event-name">${event.event_name}</div>
|
|
||||||
<div class="category">${event.event_category} | ${event.priority}</div>
|
|
||||||
<div style="margin-top: 10px;">
|
|
||||||
${event.parameters.split(',').map(p =>
|
|
||||||
`<span class="param-badge">${p.trim()}</span>`
|
|
||||||
).join('')}
|
|
||||||
</div>
|
|
||||||
<div style="margin-top: 10px; color: #5f6368;">${event.notes}</div>
|
|
||||||
</div>
|
|
||||||
`).join('');
|
|
||||||
}
|
|
||||||
|
|
||||||
function debounce(func, wait) {
|
|
||||||
let timeout;
|
|
||||||
return function(...args) {
|
|
||||||
clearTimeout(timeout);
|
|
||||||
timeout = setTimeout(() => func.apply(this, args), wait);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Deployment
|
|
||||||
|
|
||||||
### 1. Deploy as Web App
|
|
||||||
```
|
|
||||||
1. Deploy > New deployment
|
|
||||||
2. Type: Web app
|
|
||||||
3. Execute as: Me
|
|
||||||
4. Access: Anyone within organization (또는 Anyone)
|
|
||||||
5. Deploy
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Get Web App URL
|
|
||||||
```
|
|
||||||
배포 후 제공되는 URL 복사
|
|
||||||
https://script.google.com/macros/s/[ID]/exec
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Share with Team
|
|
||||||
- URL을 Notion/Slack에 공유
|
|
||||||
- 북마크 권장
|
|
||||||
|
|
||||||
## Features Roadmap
|
|
||||||
|
|
||||||
### Phase 1 (MVP)
|
|
||||||
- [x] 이벤트 검색
|
|
||||||
- [x] 파라미터 조회
|
|
||||||
- [x] 우선순위 필터
|
|
||||||
|
|
||||||
### Phase 2
|
|
||||||
- [ ] DataLayer 코드 스니펫 복사
|
|
||||||
- [ ] 플랫폼별 코드 예시
|
|
||||||
- [ ] 최근 조회 히스토리
|
|
||||||
|
|
||||||
### Phase 3
|
|
||||||
- [ ] 이벤트 추가/수정 폼
|
|
||||||
- [ ] 변경 이력 추적
|
|
||||||
- [ ] Slack 알림 연동
|
|
||||||
|
|
||||||
## Maintenance
|
|
||||||
|
|
||||||
### Data Update
|
|
||||||
1. Google Sheets 원본 데이터 수정
|
|
||||||
2. Web App 자동 반영 (실시간)
|
|
||||||
|
|
||||||
### Code Update
|
|
||||||
1. Apps Script 수정
|
|
||||||
2. Deploy > Manage deployments
|
|
||||||
3. New version 배포
|
|
||||||
|
|
||||||
### Backup
|
|
||||||
- Google Sheets 자동 버전 히스토리
|
|
||||||
- 주기적 수동 백업 권장
|
|
||||||
|
|
||||||
## Access Control
|
|
||||||
|
|
||||||
| Role | Access Level |
|
|
||||||
|------|--------------|
|
|
||||||
| Admin | 시트 편집 + 스크립트 수정 |
|
|
||||||
| Editor | 시트 편집 |
|
|
||||||
| Viewer | Web App 조회만 |
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
| Issue | Solution |
|
|
||||||
|-------|----------|
|
|
||||||
| 앱 로딩 느림 | 데이터 캐싱 구현 |
|
|
||||||
| 검색 결과 없음 | 검색어 확인, 데이터 존재 확인 |
|
|
||||||
| 권한 오류 | 배포 설정에서 접근 권한 확인 |
|
|
||||||
| 데이터 미반영 | 시트 새로고침, 캐시 클리어 |
|
|
||||||
|
|
||||||
## Integration with Notion
|
|
||||||
|
|
||||||
Web App URL을 Notion에 embed:
|
|
||||||
```
|
|
||||||
/embed [Web App URL]
|
|
||||||
```
|
|
||||||
|
|
||||||
또는 iframe으로 직접 삽입.
|
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
# Platform Event Mapping Reference
|
|
||||||
|
|
||||||
GA4, Google Ads, Meta Pixel, Kakao Pixel 간 이벤트 매핑.
|
|
||||||
|
|
||||||
## E-commerce Events
|
|
||||||
|
|
||||||
| User Action | GA4 | Meta | Kakao | Google Ads |
|
|
||||||
|-------------|-----|------|-------|------------|
|
|
||||||
| 상품 목록 조회 | view_item_list | ViewContent | viewContent | - |
|
|
||||||
| 상품 상세 조회 | view_item | ViewContent | viewContent | - |
|
|
||||||
| 상품 검색 | search | Search | search | - |
|
|
||||||
| 장바구니 담기 | add_to_cart | AddToCart | addToCart | - |
|
|
||||||
| 위시리스트 | add_to_wishlist | AddToWishlist | addToWishlist | - |
|
|
||||||
| 결제 시작 | begin_checkout | InitiateCheckout | beginCheckout | - |
|
|
||||||
| 배송정보 입력 | add_shipping_info | - | - | - |
|
|
||||||
| 결제정보 입력 | add_payment_info | AddPaymentInfo | addPaymentInfo | - |
|
|
||||||
| 구매 완료 | purchase | Purchase | purchase | purchase |
|
|
||||||
|
|
||||||
## Lead Gen Events
|
|
||||||
|
|
||||||
| User Action | GA4 | Meta | Kakao | Google Ads |
|
|
||||||
|-------------|-----|------|-------|------------|
|
|
||||||
| 회원가입 | sign_up | CompleteRegistration | completeRegistration | sign_up |
|
|
||||||
| 로그인 | login | - | login | - |
|
|
||||||
| 리드 생성 | generate_lead | Lead | participation | submit_lead_form |
|
|
||||||
|
|
||||||
## Engagement Events
|
|
||||||
|
|
||||||
| User Action | GA4 | Meta | Kakao | Google Ads |
|
|
||||||
|-------------|-----|------|-------|------------|
|
|
||||||
| 페이지 조회 | page_view | PageView | pageView | page_view |
|
|
||||||
| 검색 | search | Search | search | - |
|
|
||||||
| 공유 | share | - | - | - |
|
|
||||||
|
|
||||||
## Parameter Transformation
|
|
||||||
|
|
||||||
### GA4 → Meta
|
|
||||||
```javascript
|
|
||||||
// GA4 items[] → Meta content_ids[]
|
|
||||||
const contentIds = items.map(item => item.item_id);
|
|
||||||
|
|
||||||
// Meta Purchase
|
|
||||||
fbq('track', 'Purchase', {
|
|
||||||
content_ids: contentIds,
|
|
||||||
content_type: 'product',
|
|
||||||
value: ecommerce.value,
|
|
||||||
currency: 'KRW',
|
|
||||||
num_items: items.length
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### GA4 → Kakao
|
|
||||||
```javascript
|
|
||||||
// GA4 items[] → Kakao products[]
|
|
||||||
const products = items.map(item => ({
|
|
||||||
id: item.item_id,
|
|
||||||
name: item.item_name,
|
|
||||||
price: item.price,
|
|
||||||
quantity: item.quantity
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Kakao purchase
|
|
||||||
kakaoPixel('PIXEL_ID').purchase({
|
|
||||||
total_price: ecommerce.value,
|
|
||||||
currency: 'KRW',
|
|
||||||
products: products
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## GTM Variables
|
|
||||||
|
|
||||||
### CJS - Item IDs for Meta
|
|
||||||
```javascript
|
|
||||||
function() {
|
|
||||||
var items = {{DLV - ecommerce.items}} || [];
|
|
||||||
return items.map(function(item) {
|
|
||||||
return item.item_id;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### CJS - Products for Kakao
|
|
||||||
```javascript
|
|
||||||
function() {
|
|
||||||
var items = {{DLV - ecommerce.items}} || [];
|
|
||||||
return items.map(function(item) {
|
|
||||||
return {
|
|
||||||
id: item.item_id,
|
|
||||||
name: item.item_name,
|
|
||||||
price: item.price,
|
|
||||||
quantity: item.quantity
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Deduplication
|
|
||||||
|
|
||||||
### Event ID Pattern
|
|
||||||
```javascript
|
|
||||||
var eventId = 'evt_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
|
|
||||||
|
|
||||||
// Client-side
|
|
||||||
fbq('track', 'Purchase', {...}, {eventID: eventId});
|
|
||||||
|
|
||||||
// Server-side (CAPI)
|
|
||||||
// 동일한 eventId 사용 → Meta 자동 중복 제거
|
|
||||||
```
|
|
||||||
|
|
||||||
## Platform-specific Notes
|
|
||||||
|
|
||||||
### Meta Pixel
|
|
||||||
- content_type: 'product' (상품) / 'product_group' (변형)
|
|
||||||
- currency: ISO 4217 필수
|
|
||||||
- value: 숫자 (소수점 가능)
|
|
||||||
|
|
||||||
### Kakao Pixel
|
|
||||||
- Server-side 미지원 (Client-only)
|
|
||||||
- products[]: 최대 10개 권장
|
|
||||||
- total_price: 숫자
|
|
||||||
|
|
||||||
### Google Ads
|
|
||||||
- Enhanced Conversions 권장
|
|
||||||
- transaction_id 필수 (중복 제거용)
|
|
||||||
- value: KRW 정수
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
# GTM Implementation QA Checklist
|
|
||||||
|
|
||||||
태깅 구현 품질 검증 체크리스트.
|
|
||||||
|
|
||||||
## 1. Pre-Implementation
|
|
||||||
|
|
||||||
### Documentation
|
|
||||||
- [ ] Tagging Plan 승인 완료
|
|
||||||
- [ ] DataLayer 스키마 개발팀 공유
|
|
||||||
- [ ] 이벤트 택소노미 합의 완료
|
|
||||||
|
|
||||||
### Access
|
|
||||||
- [ ] GTM 컨테이너 접근 권한
|
|
||||||
- [ ] GA4 속성 접근 권한
|
|
||||||
- [ ] 광고 플랫폼 접근 권한
|
|
||||||
|
|
||||||
### Tools
|
|
||||||
- [ ] GTM Preview 모드 정상
|
|
||||||
- [ ] GA4 DebugView 활성화
|
|
||||||
- [ ] Chrome DevTools 준비
|
|
||||||
|
|
||||||
## 2. DataLayer Validation
|
|
||||||
|
|
||||||
### Base Setup
|
|
||||||
- [ ] GTM 스니펫 이전 dataLayer 초기화
|
|
||||||
- [ ] 페이지 로드 시 기본 데이터 push
|
|
||||||
- [ ] pageType, userId 등 기본 변수 존재
|
|
||||||
|
|
||||||
### Data Types
|
|
||||||
- [ ] 숫자 값이 Number 타입
|
|
||||||
- [ ] 금액에 통화 코드 포함 (KRW)
|
|
||||||
- [ ] transaction_id 유니크
|
|
||||||
|
|
||||||
### E-commerce
|
|
||||||
- [ ] ecommerce: null 선행 push
|
|
||||||
- [ ] items[] 배열 구조 정확
|
|
||||||
- [ ] 필수 파라미터 완비
|
|
||||||
|
|
||||||
### Console Check
|
|
||||||
```javascript
|
|
||||||
console.log(window.dataLayer);
|
|
||||||
dataLayer.filter(e => e.event === 'purchase');
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3. Tag Firing
|
|
||||||
|
|
||||||
### GA4
|
|
||||||
| Tag | Trigger | Status |
|
|
||||||
|-----|---------|--------|
|
|
||||||
| Config | All Pages | [ ] |
|
|
||||||
| view_item | Product page | [ ] |
|
|
||||||
| add_to_cart | Add button | [ ] |
|
|
||||||
| begin_checkout | Checkout start | [ ] |
|
|
||||||
| purchase | Thank you | [ ] |
|
|
||||||
|
|
||||||
### Google Ads
|
|
||||||
| Conversion | Trigger | Status |
|
|
||||||
|------------|---------|--------|
|
|
||||||
| Purchase | DL - purchase | [ ] |
|
|
||||||
| Lead | DL - generate_lead | [ ] |
|
|
||||||
|
|
||||||
### Meta Pixel
|
|
||||||
| Event | Trigger | Status |
|
|
||||||
|-------|---------|--------|
|
|
||||||
| PageView | All Pages | [ ] |
|
|
||||||
| ViewContent | Product | [ ] |
|
|
||||||
| AddToCart | Add | [ ] |
|
|
||||||
| Purchase | Thank you | [ ] |
|
|
||||||
|
|
||||||
### Kakao Pixel
|
|
||||||
| Event | Trigger | Status |
|
|
||||||
|-------|---------|--------|
|
|
||||||
| pageView | All Pages | [ ] |
|
|
||||||
| purchase | Thank you | [ ] |
|
|
||||||
|
|
||||||
## 4. Network Validation
|
|
||||||
|
|
||||||
### Endpoints
|
|
||||||
```
|
|
||||||
GA4: google-analytics.com/g/collect
|
|
||||||
GAds: googleads.g.doubleclick.net/pagead/conversion/
|
|
||||||
Meta: facebook.com/tr/
|
|
||||||
```
|
|
||||||
|
|
||||||
### Check Points
|
|
||||||
- [ ] 요청 전송됨
|
|
||||||
- [ ] 파라미터 정확
|
|
||||||
- [ ] 응답 성공 (200/204)
|
|
||||||
|
|
||||||
## 5. Cross-browser Testing
|
|
||||||
|
|
||||||
### Desktop
|
|
||||||
- [ ] Chrome
|
|
||||||
- [ ] Safari
|
|
||||||
- [ ] Firefox
|
|
||||||
- [ ] Edge
|
|
||||||
|
|
||||||
### Mobile
|
|
||||||
- [ ] iOS Safari
|
|
||||||
- [ ] iOS Chrome
|
|
||||||
- [ ] Android Chrome
|
|
||||||
|
|
||||||
## 6. Data Validation (Platform)
|
|
||||||
|
|
||||||
### GA4
|
|
||||||
- [ ] Realtime 보고서 이벤트 표시
|
|
||||||
- [ ] 파라미터 정확히 수집
|
|
||||||
- [ ] E-commerce 보고서 정확
|
|
||||||
|
|
||||||
### Google Ads
|
|
||||||
- [ ] 전환 액션 데이터 유입
|
|
||||||
- [ ] 전환 값 정확
|
|
||||||
|
|
||||||
### Meta
|
|
||||||
- [ ] Events Manager 수신 확인
|
|
||||||
- [ ] Event match quality 확인
|
|
||||||
|
|
||||||
## 7. Edge Cases
|
|
||||||
|
|
||||||
- [ ] 빈 장바구니 결제 시작 처리
|
|
||||||
- [ ] 0개 구매 처리
|
|
||||||
- [ ] 쿠폰 없는 구매
|
|
||||||
- [ ] 게스트 체크아웃
|
|
||||||
- [ ] 새로고침 시 중복 방지
|
|
||||||
- [ ] 뒤로가기 시 처리
|
|
||||||
|
|
||||||
## 8. Performance & Privacy
|
|
||||||
|
|
||||||
### Performance
|
|
||||||
- [ ] 태그 로딩이 렌더링 차단 안 함
|
|
||||||
- [ ] 비동기 로딩
|
|
||||||
|
|
||||||
### Privacy
|
|
||||||
- [ ] 동의 없이 태그 미발화 (CMP 시)
|
|
||||||
- [ ] PII 직접 수집 없음
|
|
||||||
|
|
||||||
## Sign-off
|
|
||||||
|
|
||||||
| Role | Name | Date | ✓ |
|
|
||||||
|------|------|------|---|
|
|
||||||
| QA Lead | | | |
|
|
||||||
| Analytics Lead | | | |
|
|
||||||
| Dev Lead | | | |
|
|
||||||
|
|
||||||
## Issues Log
|
|
||||||
|
|
||||||
| # | Issue | Severity | Status |
|
|
||||||
|---|-------|----------|--------|
|
|
||||||
| 1 | | High/Med/Low | Open/Resolved |
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
# GTM Guardian Scripts
|
|
||||||
|
|
||||||
이 디렉토리는 GTM Guardian Code 스킬의 자동화 스크립트 저장소입니다.
|
|
||||||
|
|
||||||
## D.intelligence GTM Toolkit
|
|
||||||
|
|
||||||
메인 분석 도구는 별도 레포지토리에서 관리됩니다:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/ourdigital/dintel-gtm-agent.git
|
|
||||||
```
|
|
||||||
|
|
||||||
## 사용법
|
|
||||||
|
|
||||||
GTM Toolkit 클론 후:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Container 분석
|
|
||||||
python analyze_container.py GTM-XXXXXX.json --output report.md
|
|
||||||
|
|
||||||
# 버전 비교
|
|
||||||
python diff_versions.py v1.json v2.json --output diff.md
|
|
||||||
|
|
||||||
# 미사용 요소 탐지
|
|
||||||
python find_unused.py container.json --type all
|
|
||||||
```
|
|
||||||
|
|
||||||
## 향후 추가 예정
|
|
||||||
|
|
||||||
- GTM Container Export 자동화 스크립트
|
|
||||||
- Notion 리포트 업로드 스크립트
|
|
||||||
- 정기 감사 자동화 (cron job)
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
---
|
|
||||||
name: gtm-guardian
|
|
||||||
description: |
|
|
||||||
GTM tagging lifecycle manager: analysis, planning, taxonomy, implementation guide.
|
|
||||||
Triggers: GTM strategy, tagging plan, event taxonomy, implementation guide.
|
|
||||||
---
|
|
||||||
|
|
||||||
# GTM Guardian (Desktop)
|
|
||||||
|
|
||||||
GTM(Google Tag Manager) 태깅 전략 수립부터 구현까지의 전체 라이프사이클을 지원하는 7단계 워크플로우 스킬.
|
|
||||||
|
|
||||||
**Desktop 범위**: Phase 1-5 (분석, 설계, 문서 작성, Browser 분석, Notion 연동)
|
|
||||||
|
|
||||||
## 7-Phase Workflow Overview
|
|
||||||
|
|
||||||
| Phase | Name | Output | Tools |
|
|
||||||
|-------|------|--------|-------|
|
|
||||||
| 1 | Web/App Analysis | DOM 분석 리포트 | Browser MCP |
|
|
||||||
| 2 | User Behaviour & KPI | 행동 흐름도, KPI 정의서 | Notion MCP |
|
|
||||||
| 3 | Tagging Plan | 태깅 계획서 | templates/ |
|
|
||||||
| 4 | Event Taxonomy | 이벤트 택소노미 시트 | Google Sheets |
|
|
||||||
| 5 | Implementation Guide | 구현 가이드, 체크리스트 | Notion MCP |
|
|
||||||
| 6 | Progressive Audit | 진단 리포트 | **→ Claude Code** |
|
|
||||||
| 7 | Lookup App | 이벤트 조회 앱 | **→ Claude Code** |
|
|
||||||
|
|
||||||
## Quick Start
|
|
||||||
|
|
||||||
```
|
|
||||||
사용자 요청 분석 → Phase 식별 → 해당 Phase 워크플로우 실행 → Notion 저장
|
|
||||||
```
|
|
||||||
|
|
||||||
### Phase 식별 가이드
|
|
||||||
|
|
||||||
| 키워드 | Phase | Reference |
|
|
||||||
|--------|-------|-----------|
|
|
||||||
| "사이트 분석", "DOM", "요소 분석" | 1 | [phase1-analysis.md](references/phase1-analysis.md) |
|
|
||||||
| "행동 분석", "KPI", "전환 정의" | 2 | [phase2-behaviour.md](references/phase2-behaviour.md) |
|
|
||||||
| "태깅 계획", "Tagging Plan" | 3 | [phase3-tagging-plan.md](references/phase3-tagging-plan.md) |
|
|
||||||
| "이벤트 택소노미", "명명 규칙" | 4 | [phase4-taxonomy.md](references/phase4-taxonomy.md) |
|
|
||||||
| "구현 가이드", "체크리스트" | 5 | [phase5-implementation.md](references/phase5-implementation.md) |
|
|
||||||
| "진단", "감사", "업데이트" | 6 | → Claude Code 권장 |
|
|
||||||
| "조회 앱", "Lookup" | 7 | → Claude Code 권장 |
|
|
||||||
|
|
||||||
## Core References
|
|
||||||
|
|
||||||
### DataLayer & Events
|
|
||||||
- [datalayer-schema.md](references/datalayer-schema.md) - GA4 권장 이벤트 기반 DataLayer 스키마
|
|
||||||
- [platform-mapping.md](references/platform-mapping.md) - GA4, Meta, Kakao, Google Ads 이벤트 매핑
|
|
||||||
- [naming-conventions.md](references/naming-conventions.md) - 태그/트리거/변수 네이밍 규칙
|
|
||||||
|
|
||||||
### Server-side GTM
|
|
||||||
- [sgtm-guide.md](references/sgtm-guide.md) - sGTM 아키텍처 및 Stape 설정
|
|
||||||
|
|
||||||
### Implementation
|
|
||||||
- [qa-checklist.md](references/qa-checklist.md) - 구현 QA 체크리스트
|
|
||||||
|
|
||||||
### Templates
|
|
||||||
- [tagging-plan-template.md](templates/tagging-plan-template.md) - 태깅 계획서 템플릿
|
|
||||||
- [event-taxonomy-template.csv](templates/event-taxonomy-template.csv) - 이벤트 택소노미 시트 템플릿
|
|
||||||
|
|
||||||
## Notion Integration
|
|
||||||
|
|
||||||
산출물 저장 대상: [GTM Knowledge Base](https://www.notion.so/dintelligence/2cf581e58a1e80c8b358f1625356e931)
|
|
||||||
|
|
||||||
### 저장 워크플로우 (MCP)
|
|
||||||
1. `notion/API-post-search`로 대상 페이지/DB 탐색
|
|
||||||
2. Phase별 템플릿 적용하여 콘텐츠 구성
|
|
||||||
3. `notion/API-post-page`로 페이지 생성
|
|
||||||
4. 상위 페이지에 링크 추가
|
|
||||||
|
|
||||||
### Page Naming Convention
|
|
||||||
```
|
|
||||||
[Phase#] - [Project] - [Type] - [Date]
|
|
||||||
예: P3 - ClientA - Tagging Plan - 2025-01
|
|
||||||
```
|
|
||||||
|
|
||||||
## Site Type Patterns
|
|
||||||
|
|
||||||
| Site Type | Key Events | Focus Areas |
|
|
||||||
|-----------|------------|-------------|
|
|
||||||
| E-commerce | view_item, add_to_cart, purchase | Transaction, ROAS |
|
|
||||||
| Lead Gen | generate_lead, form_submit | Form tracking, Lead value |
|
|
||||||
| SaaS | sign_up, subscription_* | Activation, Retention |
|
|
||||||
| Media | article_view, scroll, video_* | Engagement depth |
|
|
||||||
| B2B | demo_request, pricing_view | Funnel progression |
|
|
||||||
|
|
||||||
## Execution Principles
|
|
||||||
|
|
||||||
1. **Phase 순서 준수**: 선행 Phase 완료 후 다음 단계
|
|
||||||
2. **문서화 우선**: 모든 결정사항 Notion에 기록
|
|
||||||
3. **점진적 구현**: 핵심 이벤트 → 확장 이벤트
|
|
||||||
4. **검증 필수**: 구현 후 QA 체크리스트 수행
|
|
||||||
5. **버전 관리**: GTM 컨테이너 버전 및 문서 버전 추적
|
|
||||||
|
|
||||||
## Browser Analysis (Phase 1)
|
|
||||||
|
|
||||||
Browser MCP 또는 Firecrawl MCP를 활용한 DOM 분석:
|
|
||||||
|
|
||||||
```
|
|
||||||
1. 페이지 렌더링 후 DOM 분석
|
|
||||||
2. 주요 요소 식별 (CTA, 폼, 상품 목록)
|
|
||||||
3. 기존 dataLayer 상태 확인
|
|
||||||
4. 트리거 가능 요소 문서화
|
|
||||||
```
|
|
||||||
|
|
||||||
## Error Handling
|
|
||||||
|
|
||||||
| Issue | Resolution |
|
|
||||||
|-------|------------|
|
|
||||||
| DataLayer 미구현 | 개발팀 가이드 제공, 우선순위 태그로 시작 |
|
|
||||||
| 이벤트 누락 | Phase 1-2 재검토 |
|
|
||||||
| 태그 미발화 | Phase 5 체크리스트, GTM Preview 디버깅 |
|
|
||||||
| 데이터 정합성 오류 | GA4 DebugView 검증 |
|
|
||||||
@@ -1,193 +0,0 @@
|
|||||||
# DataLayer Schema Reference
|
|
||||||
|
|
||||||
GA4 권장 이벤트 기반 DataLayer 스키마 정의.
|
|
||||||
|
|
||||||
## Core Principles
|
|
||||||
|
|
||||||
1. GTM 스니펫 이전에 dataLayer 초기화
|
|
||||||
2. 이벤트 발생 시점에 push (사전 아님)
|
|
||||||
3. ecommerce 객체는 push 전 clear 필수
|
|
||||||
4. PII 데이터 직접 수집 금지
|
|
||||||
|
|
||||||
## Base Structure
|
|
||||||
|
|
||||||
### Page Load
|
|
||||||
```javascript
|
|
||||||
window.dataLayer = window.dataLayer || [];
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'page_data',
|
|
||||||
'page': {
|
|
||||||
'type': 'home|category|product|cart|checkout|thankyou|content|search',
|
|
||||||
'name': 'Page Name',
|
|
||||||
'category': 'Category/Subcategory',
|
|
||||||
'language': 'ko'
|
|
||||||
},
|
|
||||||
'user': {
|
|
||||||
'status': 'logged_in|logged_out',
|
|
||||||
'id': 'hashed_user_id', // SHA256, 로그인 시에만
|
|
||||||
'type': 'new|returning|member|guest',
|
|
||||||
'loginMethod': 'email|kakao|naver|google'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## E-commerce Events
|
|
||||||
|
|
||||||
### view_item
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'view_item',
|
|
||||||
'ecommerce': {
|
|
||||||
'currency': 'KRW',
|
|
||||||
'value': 29000,
|
|
||||||
'items': [{
|
|
||||||
'item_id': 'SKU_12345',
|
|
||||||
'item_name': 'Product Name',
|
|
||||||
'item_brand': 'Brand Name',
|
|
||||||
'item_category': 'Category',
|
|
||||||
'item_variant': 'Blue / Large',
|
|
||||||
'price': 29000,
|
|
||||||
'quantity': 1
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### add_to_cart
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'add_to_cart',
|
|
||||||
'ecommerce': {
|
|
||||||
'currency': 'KRW',
|
|
||||||
'value': 29000,
|
|
||||||
'items': [{
|
|
||||||
'item_id': 'SKU_12345',
|
|
||||||
'item_name': 'Product Name',
|
|
||||||
'price': 29000,
|
|
||||||
'quantity': 1
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### begin_checkout
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'begin_checkout',
|
|
||||||
'ecommerce': {
|
|
||||||
'currency': 'KRW',
|
|
||||||
'value': 58000,
|
|
||||||
'coupon': 'WELCOME10',
|
|
||||||
'items': [/* cart items */]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### purchase
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null });
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'purchase',
|
|
||||||
'ecommerce': {
|
|
||||||
'transaction_id': 'T_20250115_001',
|
|
||||||
'affiliation': 'Store Name',
|
|
||||||
'value': 53000,
|
|
||||||
'tax': 4818,
|
|
||||||
'shipping': 3000,
|
|
||||||
'currency': 'KRW',
|
|
||||||
'coupon': 'WELCOME10',
|
|
||||||
'items': [{
|
|
||||||
'item_id': 'SKU_12345',
|
|
||||||
'item_name': 'Product Name',
|
|
||||||
'price': 29000,
|
|
||||||
'quantity': 1
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Lead Gen Events
|
|
||||||
|
|
||||||
### generate_lead
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'generate_lead',
|
|
||||||
'currency': 'KRW',
|
|
||||||
'value': 50000,
|
|
||||||
'lead': {
|
|
||||||
'source': 'contact_form|landing_page',
|
|
||||||
'type': 'inquiry|quote_request'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### form_submit
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'form_submit',
|
|
||||||
'form': {
|
|
||||||
'id': 'contact_form',
|
|
||||||
'name': 'Contact Us Form',
|
|
||||||
'type': 'contact',
|
|
||||||
'success': true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Engagement Events
|
|
||||||
|
|
||||||
### login / sign_up
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'login', // or 'sign_up'
|
|
||||||
'method': 'email|kakao|naver|google'
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### search
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'search',
|
|
||||||
'search_term': 'user search query',
|
|
||||||
'search': {
|
|
||||||
'results_count': 42,
|
|
||||||
'category': 'product|content'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Item Object Reference
|
|
||||||
|
|
||||||
| Parameter | Type | Required | Description |
|
|
||||||
|-----------|------|----------|-------------|
|
|
||||||
| item_id | string | Yes | SKU |
|
|
||||||
| item_name | string | Yes | 상품명 |
|
|
||||||
| price | number | Yes | 단가 |
|
|
||||||
| quantity | number | Yes | 수량 |
|
|
||||||
| item_brand | string | No | 브랜드명 |
|
|
||||||
| item_category | string | No | 카테고리 |
|
|
||||||
| item_category2-5 | string | No | 하위 카테고리 |
|
|
||||||
| item_variant | string | No | 옵션 |
|
|
||||||
| coupon | string | No | 쿠폰 코드 |
|
|
||||||
| discount | number | No | 할인 금액 |
|
|
||||||
| index | number | No | 목록 위치 |
|
|
||||||
|
|
||||||
## Validation Rules
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// ✅ Correct
|
|
||||||
'price': 29000 // number
|
|
||||||
'quantity': 1 // number
|
|
||||||
'currency': 'KRW' // uppercase
|
|
||||||
|
|
||||||
// ❌ Wrong
|
|
||||||
'price': '29000' // string
|
|
||||||
'currency': 'krw' // lowercase
|
|
||||||
```
|
|
||||||
|
|
||||||
### Array Limits
|
|
||||||
- items[]: 최대 200개
|
|
||||||
- 초과 시 분할 전송
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
# GTM Naming Conventions
|
|
||||||
|
|
||||||
일관된 GTM 컨테이너 관리를 위한 네이밍 규칙.
|
|
||||||
|
|
||||||
## Tag Naming
|
|
||||||
|
|
||||||
### Pattern
|
|
||||||
```
|
|
||||||
[Platform] - [Type] - [Description]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
| Platform | Type | Description | Tag Name |
|
|
||||||
|----------|------|-------------|----------|
|
|
||||||
| GA4 | Config | Main | GA4 - Config - Main |
|
|
||||||
| GA4 | Event | purchase | GA4 - Event - purchase |
|
|
||||||
| GAds | Conversion | Purchase | GAds - Conversion - Purchase |
|
|
||||||
| Meta | Event | Purchase | Meta - Event - Purchase |
|
|
||||||
| Kakao | Event | purchase | Kakao - Event - purchase |
|
|
||||||
|
|
||||||
## Trigger Naming
|
|
||||||
|
|
||||||
### Pattern
|
|
||||||
```
|
|
||||||
[Type] - [Condition] - [Context]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Type Codes
|
|
||||||
| Code | Type | Example |
|
|
||||||
|------|------|---------|
|
|
||||||
| PV | Page View | PV - All Pages |
|
|
||||||
| DL | DataLayer Event | DL - purchase |
|
|
||||||
| Click | Click | Click - CTA Button |
|
|
||||||
| Form | Form Submit | Form - Contact |
|
|
||||||
| Scroll | Scroll Depth | Scroll - 75% |
|
|
||||||
| Vis | Element Visibility | Vis - Video Player |
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
```
|
|
||||||
PV - All Pages
|
|
||||||
PV - Thank You Page
|
|
||||||
DL - purchase
|
|
||||||
DL - add_to_cart
|
|
||||||
Click - CTA Button - Hero
|
|
||||||
Form - Contact Form
|
|
||||||
Scroll - 90%
|
|
||||||
```
|
|
||||||
|
|
||||||
## Variable Naming
|
|
||||||
|
|
||||||
### Pattern
|
|
||||||
```
|
|
||||||
[Type] - [Name/Path]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Type Codes
|
|
||||||
| Code | Type | Example |
|
|
||||||
|------|------|---------|
|
|
||||||
| DLV | DataLayer Variable | DLV - ecommerce.value |
|
|
||||||
| CJS | Custom JavaScript | CJS - Item IDs Array |
|
|
||||||
| Const | Constant | Const - GA4 Measurement ID |
|
|
||||||
| LT | Lookup Table | LT - Page Type Mapping |
|
|
||||||
| URL | URL Variable | URL - Path |
|
|
||||||
| DOM | DOM Element | DOM - Product Title |
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
```
|
|
||||||
DLV - event
|
|
||||||
DLV - ecommerce.transaction_id
|
|
||||||
DLV - ecommerce.items
|
|
||||||
CJS - Items for Meta
|
|
||||||
CJS - Formatted Price
|
|
||||||
Const - GA4 Measurement ID
|
|
||||||
Const - Meta Pixel ID
|
|
||||||
LT - Payment Method Mapping
|
|
||||||
```
|
|
||||||
|
|
||||||
## Folder Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
📁 01. Configuration
|
|
||||||
📁 02. GA4 Events
|
|
||||||
📁 03. Google Ads
|
|
||||||
📁 04. Meta Pixel
|
|
||||||
📁 05. Kakao Pixel
|
|
||||||
📁 06. Other Platforms
|
|
||||||
📁 07. Utilities
|
|
||||||
📁 99. Deprecated
|
|
||||||
```
|
|
||||||
|
|
||||||
## Built-in Variables to Enable
|
|
||||||
|
|
||||||
```
|
|
||||||
Pages: ✅ Page URL, Path, Hostname, Referrer
|
|
||||||
Utilities: ✅ Event, Container ID, Random Number
|
|
||||||
Clicks: ✅ Element, Classes, ID, URL, Text
|
|
||||||
Forms: ✅ Element, Classes, ID, URL, Text
|
|
||||||
History: ✅ New/Old History Fragment/State
|
|
||||||
Videos: ✅ All YouTube variables
|
|
||||||
Scrolling: ✅ Depth Threshold, Units, Direction
|
|
||||||
Visibility: ✅ Percent Visible, On-Screen Duration
|
|
||||||
```
|
|
||||||
|
|
||||||
## Anti-patterns
|
|
||||||
|
|
||||||
```
|
|
||||||
❌ Tag 1, New Tag, Test
|
|
||||||
❌ GA4 purchase event (일관성 없음)
|
|
||||||
❌ G4-E-Pch (과도한 약어)
|
|
||||||
❌ Very Long Tag Name for Purchase Complete Event (너무 김)
|
|
||||||
|
|
||||||
✅ GA4 - Event - purchase
|
|
||||||
✅ DL - purchase
|
|
||||||
✅ CJS - Items for Meta
|
|
||||||
```
|
|
||||||
|
|
||||||
## Version Notes
|
|
||||||
|
|
||||||
```
|
|
||||||
v[Major].[Minor] - [Description]
|
|
||||||
예: v12.1 - Added form_submit event
|
|
||||||
|
|
||||||
## Changes
|
|
||||||
- Added:
|
|
||||||
- Modified:
|
|
||||||
- Removed:
|
|
||||||
|
|
||||||
## Reason
|
|
||||||
[변경 이유]
|
|
||||||
```
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
# Phase 1: Web/App Analysis
|
|
||||||
|
|
||||||
웹사이트 또는 앱의 태깅 가능 요소를 분석하여 DOM 구조, 동적 요소, 트리거 포인트를 파악.
|
|
||||||
|
|
||||||
## Objectives
|
|
||||||
|
|
||||||
1. Rendered HTML 소스 분석
|
|
||||||
2. DOM 구조 및 주요 요소 식별
|
|
||||||
3. 동적 요소 및 SPA 동작 파악
|
|
||||||
4. 트리거 구성 가능 요소 도출
|
|
||||||
|
|
||||||
## Analysis Checklist
|
|
||||||
|
|
||||||
### 1. Page Structure
|
|
||||||
- [ ] 페이지 유형 분류 (home, category, product, cart, checkout, thankyou)
|
|
||||||
- [ ] URL 패턴 분석 (path, query params)
|
|
||||||
- [ ] 페이지 템플릿 구조 파악
|
|
||||||
|
|
||||||
### 2. Interactive Elements
|
|
||||||
- [ ] CTA 버튼 (class, id, data-* attributes)
|
|
||||||
- [ ] 폼 요소 (form id, input names)
|
|
||||||
- [ ] 네비게이션 링크
|
|
||||||
- [ ] 아코디언/탭/모달 요소
|
|
||||||
|
|
||||||
### 3. E-commerce Elements (해당 시)
|
|
||||||
- [ ] 상품 목록 컨테이너
|
|
||||||
- [ ] 상품 카드 구조 (SKU, price, name 위치)
|
|
||||||
- [ ] 장바구니 버튼
|
|
||||||
- [ ] 결제 버튼
|
|
||||||
- [ ] 주문 완료 정보 위치
|
|
||||||
|
|
||||||
### 4. Dynamic Content
|
|
||||||
- [ ] SPA/Ajax 로딩 패턴
|
|
||||||
- [ ] Infinite scroll
|
|
||||||
- [ ] Dynamic pricing
|
|
||||||
- [ ] User-dependent content
|
|
||||||
|
|
||||||
## Browser Analysis Steps
|
|
||||||
|
|
||||||
```
|
|
||||||
1. DevTools Console에서 dataLayer 확인
|
|
||||||
> window.dataLayer
|
|
||||||
|
|
||||||
2. DOM 구조 분석
|
|
||||||
> document.querySelectorAll('[data-gtm]')
|
|
||||||
> document.querySelectorAll('form')
|
|
||||||
> document.querySelectorAll('[class*="cta"], [class*="button"]')
|
|
||||||
|
|
||||||
3. 네트워크 탭에서 기존 태그 확인
|
|
||||||
> google-analytics.com, googletagmanager.com 요청 필터
|
|
||||||
|
|
||||||
4. 이벤트 리스너 확인
|
|
||||||
> getEventListeners(document.querySelector('#element'))
|
|
||||||
```
|
|
||||||
|
|
||||||
## Output Template
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# [사이트명] DOM Analysis Report
|
|
||||||
|
|
||||||
## Site Overview
|
|
||||||
- **URL**:
|
|
||||||
- **Type**: E-commerce / Lead Gen / SaaS / Media / B2B
|
|
||||||
- **Framework**: WordPress / React / Vue / Custom
|
|
||||||
|
|
||||||
## Page Types Identified
|
|
||||||
| Page Type | URL Pattern | Key Elements |
|
|
||||||
|-----------|-------------|--------------|
|
|
||||||
| Home | / | hero_cta, featured_products |
|
|
||||||
| Product | /product/* | add_to_cart, product_details |
|
|
||||||
|
|
||||||
## Taggable Elements
|
|
||||||
### Buttons & CTAs
|
|
||||||
| Element | Selector | Current ID/Class | Recommended Trigger |
|
|
||||||
|---------|----------|------------------|---------------------|
|
|
||||||
| Add to Cart | .add-to-cart | N/A | Click - Class Match |
|
|
||||||
|
|
||||||
### Forms
|
|
||||||
| Form | ID/Name | Fields | Submit Button |
|
|
||||||
|------|---------|--------|---------------|
|
|
||||||
|
|
||||||
### Dynamic Elements
|
|
||||||
| Element | Type | Loading Pattern | Trigger Strategy |
|
|
||||||
|---------|------|-----------------|------------------|
|
|
||||||
|
|
||||||
## Existing GTM/Analytics
|
|
||||||
- [ ] GTM Container: GTM-XXXXXX
|
|
||||||
- [ ] GA4: G-XXXXXXXX
|
|
||||||
- [ ] Other pixels:
|
|
||||||
|
|
||||||
## Recommendations
|
|
||||||
1.
|
|
||||||
2.
|
|
||||||
```
|
|
||||||
|
|
||||||
## Common Patterns
|
|
||||||
|
|
||||||
### WordPress/WooCommerce
|
|
||||||
- Product: `.single-product`, `add_to_cart` class
|
|
||||||
- Cart: `.woocommerce-cart-form`
|
|
||||||
- Checkout: `.woocommerce-checkout`
|
|
||||||
|
|
||||||
### Shopify
|
|
||||||
- Product: data-product-id attribute
|
|
||||||
- Cart: form[action="/cart/add"]
|
|
||||||
- Checkout: checkout.shopify.com 별도 도메인
|
|
||||||
|
|
||||||
### React/SPA
|
|
||||||
- History API 변경 감지 필요
|
|
||||||
- Custom Event 트리거 활용
|
|
||||||
- MutationObserver 고려
|
|
||||||
|
|
||||||
## Next Phase
|
|
||||||
|
|
||||||
분석 완료 후 → Phase 2: User Behaviour Modeling
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
# Phase 2: User Behaviour Modeling & KPI Definition
|
|
||||||
|
|
||||||
사용자의 웹/앱 사용 흐름을 분석하고, 중점 관리 행동과 KPI를 정의.
|
|
||||||
|
|
||||||
## Objectives
|
|
||||||
|
|
||||||
1. 사용자 여정(User Journey) 매핑
|
|
||||||
2. 핵심 전환 포인트(Conversion Points) 식별
|
|
||||||
3. KPI 및 측정 지표 정의
|
|
||||||
4. 이벤트 우선순위 결정
|
|
||||||
|
|
||||||
## User Journey Framework
|
|
||||||
|
|
||||||
### Standard Funnel Stages
|
|
||||||
```
|
|
||||||
Awareness → Interest → Consideration → Intent → Purchase → Loyalty
|
|
||||||
↓ ↓ ↓ ↓ ↓ ↓
|
|
||||||
Landing Browse View Item Add Cart Checkout Repeat
|
|
||||||
```
|
|
||||||
|
|
||||||
### Site Type별 Journey
|
|
||||||
|
|
||||||
#### E-commerce
|
|
||||||
```
|
|
||||||
Landing → Category → Product View → Add to Cart → Checkout → Purchase
|
|
||||||
↓
|
|
||||||
Wishlist/Compare
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Lead Generation
|
|
||||||
```
|
|
||||||
Landing → Content Browse → Form View → Form Start → Form Submit → Thank You
|
|
||||||
↓
|
|
||||||
Chat/Call CTA
|
|
||||||
```
|
|
||||||
|
|
||||||
#### SaaS
|
|
||||||
```
|
|
||||||
Landing → Pricing → Sign Up Start → Email Verify → Onboarding → Activation
|
|
||||||
↓
|
|
||||||
Demo Request
|
|
||||||
```
|
|
||||||
|
|
||||||
## Conversion Points Definition
|
|
||||||
|
|
||||||
### Macro Conversions (Hard)
|
|
||||||
| Conversion | Business Value | Typical Events |
|
|
||||||
|------------|----------------|----------------|
|
|
||||||
| Purchase | Revenue | purchase |
|
|
||||||
| Lead Submit | Lead value | generate_lead |
|
|
||||||
| Sign Up | LTV estimate | sign_up |
|
|
||||||
| Subscription | MRR | subscribe |
|
|
||||||
|
|
||||||
### Micro Conversions (Soft)
|
|
||||||
| Conversion | Intent Signal | Typical Events |
|
|
||||||
|------------|---------------|----------------|
|
|
||||||
| Add to Cart | Purchase intent | add_to_cart |
|
|
||||||
| Form Start | Engagement | form_start |
|
|
||||||
| Video Complete | Content consumption | video_complete |
|
|
||||||
| Scroll 75% | Page engagement | scroll |
|
|
||||||
|
|
||||||
## KPI Framework
|
|
||||||
|
|
||||||
### SMART KPI Template
|
|
||||||
```
|
|
||||||
Metric: [이름]
|
|
||||||
Definition: [정의]
|
|
||||||
Formula: [계산식]
|
|
||||||
Target: [목표값]
|
|
||||||
Tracking Event: [관련 이벤트]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Standard E-commerce KPIs
|
|
||||||
| KPI | Formula | Events Required |
|
|
||||||
|-----|---------|-----------------|
|
|
||||||
| Conversion Rate | transactions / sessions | purchase, session_start |
|
|
||||||
| AOV | revenue / transactions | purchase |
|
|
||||||
| Cart Abandonment | 1 - (purchases / carts) | add_to_cart, purchase |
|
|
||||||
| Product View Rate | product_views / sessions | view_item |
|
|
||||||
|
|
||||||
### Lead Gen KPIs
|
|
||||||
| KPI | Formula | Events Required |
|
|
||||||
|-----|---------|-----------------|
|
|
||||||
| Lead Conversion Rate | leads / sessions | generate_lead |
|
|
||||||
| Form Completion Rate | submits / form_starts | form_start, form_submit |
|
|
||||||
| Cost per Lead | ad_spend / leads | generate_lead + ad data |
|
|
||||||
|
|
||||||
### Engagement KPIs
|
|
||||||
| KPI | Formula | Events Required |
|
|
||||||
|-----|---------|-----------------|
|
|
||||||
| Avg Session Duration | total_time / sessions | Enhanced Measurement |
|
|
||||||
| Pages per Session | pageviews / sessions | page_view |
|
|
||||||
| Scroll Depth | avg(scroll_percent) | scroll |
|
|
||||||
|
|
||||||
## Event Priority Matrix
|
|
||||||
|
|
||||||
### Priority 1 (Must Have)
|
|
||||||
- purchase / generate_lead (primary conversion)
|
|
||||||
- begin_checkout (funnel step)
|
|
||||||
- add_to_cart (intent signal)
|
|
||||||
- page_view (baseline)
|
|
||||||
|
|
||||||
### Priority 2 (Should Have)
|
|
||||||
- view_item (product engagement)
|
|
||||||
- form_start (form engagement)
|
|
||||||
- login / sign_up (user identity)
|
|
||||||
- search (intent signal)
|
|
||||||
|
|
||||||
### Priority 3 (Nice to Have)
|
|
||||||
- scroll_depth (engagement)
|
|
||||||
- video_progress (content consumption)
|
|
||||||
- share (virality)
|
|
||||||
- cta_click (UI interaction)
|
|
||||||
|
|
||||||
## Output Template
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# [프로젝트명] User Behaviour & KPI Report
|
|
||||||
|
|
||||||
## User Journey Map
|
|
||||||
[Mermaid diagram 또는 텍스트 플로우차트]
|
|
||||||
|
|
||||||
## Conversion Points
|
|
||||||
### Macro Conversions
|
|
||||||
| Conversion | Value | Priority | Event |
|
|
||||||
|------------|-------|----------|-------|
|
|
||||||
|
|
||||||
### Micro Conversions
|
|
||||||
| Conversion | Signal | Priority | Event |
|
|
||||||
|------------|--------|----------|-------|
|
|
||||||
|
|
||||||
## KPI Definition
|
|
||||||
### Primary KPIs
|
|
||||||
| KPI | Formula | Target | Tracking |
|
|
||||||
|-----|---------|--------|----------|
|
|
||||||
|
|
||||||
### Secondary KPIs
|
|
||||||
| KPI | Formula | Target | Tracking |
|
|
||||||
|-----|---------|--------|----------|
|
|
||||||
|
|
||||||
## Event Priority List
|
|
||||||
### Must Track (P1)
|
|
||||||
-
|
|
||||||
### Should Track (P2)
|
|
||||||
-
|
|
||||||
### Nice to Track (P3)
|
|
||||||
-
|
|
||||||
|
|
||||||
## Custom Dimensions Required
|
|
||||||
| Dimension | Scope | Values | Purpose |
|
|
||||||
|-----------|-------|--------|---------|
|
|
||||||
|
|
||||||
## Custom Metrics Required
|
|
||||||
| Metric | Type | Unit | Purpose |
|
|
||||||
|--------|------|------|---------|
|
|
||||||
```
|
|
||||||
|
|
||||||
## Stakeholder Input Needed
|
|
||||||
|
|
||||||
- Marketing: 캠페인 목표, 전환 가치
|
|
||||||
- Sales: Lead qualification criteria
|
|
||||||
- Product: 핵심 사용자 액션
|
|
||||||
- Analytics: 리포팅 요구사항
|
|
||||||
|
|
||||||
## Next Phase
|
|
||||||
|
|
||||||
KPI 정의 완료 후 → Phase 3: Tagging Plan Design
|
|
||||||
@@ -1,169 +0,0 @@
|
|||||||
# Phase 3: Tagging Plan Design
|
|
||||||
|
|
||||||
사용자 행동 흐름에 맞춘 맞춤 이벤트 정의, 명명 규칙, 파라미터, 맞춤 측정 기준/지표 설계.
|
|
||||||
|
|
||||||
## Objectives
|
|
||||||
|
|
||||||
1. Custom Event 정의
|
|
||||||
2. 이벤트 명명 규칙 수립
|
|
||||||
3. 환경 변수 및 파라미터 정의
|
|
||||||
4. Custom Dimensions/Metrics 설계
|
|
||||||
5. DataLayer 스키마 연계
|
|
||||||
|
|
||||||
## Tagging Plan Document Structure
|
|
||||||
|
|
||||||
### 1. Executive Summary
|
|
||||||
```
|
|
||||||
Project: [프로젝트명]
|
|
||||||
Client: [클라이언트명]
|
|
||||||
Website/App: [URL/앱명]
|
|
||||||
Version: 1.0
|
|
||||||
Last Updated: YYYY-MM-DD
|
|
||||||
Author: [작성자]
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Measurement Objectives
|
|
||||||
| Priority | Objective | KPI | Target |
|
|
||||||
|----------|-----------|-----|--------|
|
|
||||||
| P1 | 구매 전환 추적 | Conversion Rate | 3% |
|
|
||||||
| P2 | 장바구니 이탈 분석 | Cart Abandonment | < 70% |
|
|
||||||
|
|
||||||
### 3. Event Naming Convention
|
|
||||||
|
|
||||||
#### Pattern
|
|
||||||
```
|
|
||||||
[domain]_[action]_[object]
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Rules
|
|
||||||
- 소문자, 언더스코어 사용
|
|
||||||
- GA4 권장 이벤트 우선 사용
|
|
||||||
- 커스텀 이벤트는 접두어로 구분: `custom_`
|
|
||||||
|
|
||||||
#### Examples
|
|
||||||
| Action | Event Name | Type |
|
|
||||||
|--------|------------|------|
|
|
||||||
| 상품 조회 | view_item | Recommended |
|
|
||||||
| 장바구니 담기 | add_to_cart | Recommended |
|
|
||||||
| 위시리스트 | add_to_wishlist | Recommended |
|
|
||||||
| CTA 클릭 | custom_cta_click | Custom |
|
|
||||||
| 탭 전환 | custom_tab_change | Custom |
|
|
||||||
|
|
||||||
### 4. Parameter Design
|
|
||||||
|
|
||||||
#### Standard Parameters (GA4 Recommended)
|
|
||||||
| Parameter | Type | Required | Example |
|
|
||||||
|-----------|------|----------|---------|
|
|
||||||
| currency | string | Yes | "KRW" |
|
|
||||||
| value | number | Yes | 29000 |
|
|
||||||
| items | array | Yes | [...] |
|
|
||||||
| transaction_id | string | purchase only | "T_12345" |
|
|
||||||
|
|
||||||
#### Custom Parameters
|
|
||||||
| Parameter | Type | Scope | Description |
|
|
||||||
|-----------|------|-------|-------------|
|
|
||||||
| user_type | string | event | new/returning |
|
|
||||||
| page_type | string | event | home/product/cart |
|
|
||||||
| login_method | string | event | kakao/naver/email |
|
|
||||||
|
|
||||||
### 5. Custom Dimensions
|
|
||||||
|
|
||||||
| Name | Scope | Values | GA4 Configuration |
|
|
||||||
|------|-------|--------|-------------------|
|
|
||||||
| User Type | User | new, returning | user_type |
|
|
||||||
| Membership Level | User | bronze, silver, gold | membership_level |
|
|
||||||
| Page Type | Event | home, category, product, cart, checkout | page_type |
|
|
||||||
|
|
||||||
### 6. Custom Metrics
|
|
||||||
|
|
||||||
| Name | Unit | Description | Event Source |
|
|
||||||
|------|------|-------------|--------------|
|
|
||||||
| Wishlist Adds | Count | 위시리스트 추가 수 | add_to_wishlist |
|
|
||||||
| Form Starts | Count | 폼 시작 수 | form_start |
|
|
||||||
|
|
||||||
### 7. Environment Configuration
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// 환경 변수 설정
|
|
||||||
const GTM_CONFIG = {
|
|
||||||
development: {
|
|
||||||
gtmId: 'GTM-DEV123',
|
|
||||||
ga4Id: 'G-DEV456',
|
|
||||||
debugMode: true
|
|
||||||
},
|
|
||||||
staging: {
|
|
||||||
gtmId: 'GTM-STG123',
|
|
||||||
ga4Id: 'G-STG456',
|
|
||||||
debugMode: true
|
|
||||||
},
|
|
||||||
production: {
|
|
||||||
gtmId: 'GTM-PROD123',
|
|
||||||
ga4Id: 'G-PROD456',
|
|
||||||
debugMode: false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
### 8. Platform Mapping
|
|
||||||
|
|
||||||
| Action | GA4 | Meta | Kakao | Google Ads |
|
|
||||||
|--------|-----|------|-------|------------|
|
|
||||||
| 상품 조회 | view_item | ViewContent | viewContent | - |
|
|
||||||
| 장바구니 | add_to_cart | AddToCart | addToCart | - |
|
|
||||||
| 구매 완료 | purchase | Purchase | purchase | purchase |
|
|
||||||
|
|
||||||
→ 상세 매핑: [platform-mapping.md](platform-mapping.md)
|
|
||||||
|
|
||||||
### 9. DataLayer Requirements
|
|
||||||
|
|
||||||
→ 상세 스키마: [datalayer-schema.md](datalayer-schema.md)
|
|
||||||
|
|
||||||
## Tagging Plan Template
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# [Project] Tagging Plan v1.0
|
|
||||||
|
|
||||||
## 1. Overview
|
|
||||||
### 1.1 Project Information
|
|
||||||
### 1.2 Measurement Objectives
|
|
||||||
### 1.3 Key Conversions
|
|
||||||
|
|
||||||
## 2. Event Specification
|
|
||||||
### 2.1 Recommended Events
|
|
||||||
### 2.2 Custom Events
|
|
||||||
### 2.3 Parameter Reference
|
|
||||||
|
|
||||||
## 3. DataLayer Specification
|
|
||||||
### 3.1 Page Load Data
|
|
||||||
### 3.2 E-commerce Events
|
|
||||||
### 3.3 Engagement Events
|
|
||||||
|
|
||||||
## 4. Tag Configuration
|
|
||||||
### 4.1 GA4 Tags
|
|
||||||
### 4.2 Google Ads Tags
|
|
||||||
### 4.3 Meta Pixel Tags
|
|
||||||
### 4.4 Kakao Pixel Tags
|
|
||||||
|
|
||||||
## 5. Implementation Notes
|
|
||||||
### 5.1 Developer Requirements
|
|
||||||
### 5.2 QA Checklist
|
|
||||||
### 5.3 Timeline
|
|
||||||
|
|
||||||
## Appendix
|
|
||||||
- A. Naming Conventions
|
|
||||||
- B. Platform Event Mapping
|
|
||||||
- C. Change Log
|
|
||||||
```
|
|
||||||
|
|
||||||
## Quality Checklist
|
|
||||||
|
|
||||||
- [ ] 모든 P1 이벤트 정의됨
|
|
||||||
- [ ] 이벤트 명명 규칙 일관성
|
|
||||||
- [ ] 필수 파라미터 정의 완료
|
|
||||||
- [ ] Custom Dimensions scope 적절
|
|
||||||
- [ ] 플랫폼별 매핑 완료
|
|
||||||
- [ ] DataLayer 스키마와 정합성 확인
|
|
||||||
|
|
||||||
## Next Phase
|
|
||||||
|
|
||||||
Tagging Plan 완료 후 → Phase 4: Event Taxonomy Design
|
|
||||||
@@ -1,159 +0,0 @@
|
|||||||
# Phase 4: Event Taxonomy Design
|
|
||||||
|
|
||||||
이벤트 명명 규칙, 태그 이름, 트리거 조건, 파라미터, 맞춤 측정 기준/지표를 구글 시트로 체계화.
|
|
||||||
|
|
||||||
## Objectives
|
|
||||||
|
|
||||||
1. 이벤트 택소노미 시트 구조화
|
|
||||||
2. 태그/트리거/변수 명명 일관성
|
|
||||||
3. 파라미터 및 측정 기준 연계
|
|
||||||
4. 팀 간 공유 가능한 문서화
|
|
||||||
|
|
||||||
## Event Taxonomy Sheet Structure
|
|
||||||
|
|
||||||
### Sheet 1: Events Master
|
|
||||||
|
|
||||||
| Column | Description | Example |
|
|
||||||
|--------|-------------|---------|
|
|
||||||
| event_name | 이벤트 명 | purchase |
|
|
||||||
| event_category | 이벤트 유형 | ecommerce |
|
|
||||||
| trigger_type | 트리거 유형 | dataLayer |
|
|
||||||
| trigger_condition | 트리거 조건 | event equals 'purchase' |
|
|
||||||
| parameters | 필수 파라미터 | transaction_id, value, currency, items |
|
|
||||||
| custom_dimensions | 연계 측정기준 | user_type, payment_method |
|
|
||||||
| custom_metrics | 연계 지표 | - |
|
|
||||||
| ga4_mapping | GA4 이벤트 | purchase (recommended) |
|
|
||||||
| meta_mapping | Meta 이벤트 | Purchase |
|
|
||||||
| kakao_mapping | Kakao 이벤트 | purchase |
|
|
||||||
| priority | 우선순위 | P1 |
|
|
||||||
| notes | 비고 | 결제 완료 페이지에서 발화 |
|
|
||||||
|
|
||||||
### Sheet 2: Parameters Reference
|
|
||||||
|
|
||||||
| Column | Description | Example |
|
|
||||||
|--------|-------------|---------|
|
|
||||||
| parameter_name | 파라미터 명 | transaction_id |
|
|
||||||
| data_type | 데이터 타입 | string |
|
|
||||||
| required | 필수 여부 | Yes |
|
|
||||||
| scope | 범위 | event |
|
|
||||||
| events | 사용 이벤트 | purchase, refund |
|
|
||||||
| ga4_param | GA4 파라미터명 | transaction_id |
|
|
||||||
| datalayer_path | DL 경로 | ecommerce.transaction_id |
|
|
||||||
| validation | 검증 규칙 | not empty, unique |
|
|
||||||
| example | 예시 | "T_20250115_001" |
|
|
||||||
|
|
||||||
### Sheet 3: Custom Definitions
|
|
||||||
|
|
||||||
| Column | Description | Example |
|
|
||||||
|--------|-------------|---------|
|
|
||||||
| name | 이름 | User Type |
|
|
||||||
| type | 유형 | dimension / metric |
|
|
||||||
| scope | 범위 | user / event |
|
|
||||||
| parameter | 연계 파라미터 | user_type |
|
|
||||||
| values | 가능한 값 | new, returning |
|
|
||||||
| description | 설명 | 신규/재방문 사용자 구분 |
|
|
||||||
| ga4_index | GA4 인덱스 | - (자동생성) |
|
|
||||||
|
|
||||||
### Sheet 4: Tag Configuration
|
|
||||||
|
|
||||||
| Column | Description | Example |
|
|
||||||
|--------|-------------|---------|
|
|
||||||
| tag_name | 태그 명 | GA4 - Event - purchase |
|
|
||||||
| tag_type | 태그 유형 | GA4 Event |
|
|
||||||
| platform | 플랫폼 | GA4 |
|
|
||||||
| trigger | 트리거 명 | DL - purchase |
|
|
||||||
| blocking_trigger | 차단 트리거 | Block - Internal |
|
|
||||||
| variables | 사용 변수 | DLV - transaction_id, DLV - value |
|
|
||||||
| folder | 폴더 | 02. GA4 Events |
|
|
||||||
|
|
||||||
### Sheet 5: Trigger Configuration
|
|
||||||
|
|
||||||
| Column | Description | Example |
|
|
||||||
|--------|-------------|---------|
|
|
||||||
| trigger_name | 트리거 명 | DL - purchase |
|
|
||||||
| trigger_type | 트리거 유형 | Custom Event |
|
|
||||||
| event_name | 이벤트 명 | purchase |
|
|
||||||
| conditions | 조건 | - |
|
|
||||||
| used_by | 사용 태그 | GA4 - Event - purchase |
|
|
||||||
|
|
||||||
### Sheet 6: Variable Configuration
|
|
||||||
|
|
||||||
| Column | Description | Example |
|
|
||||||
|--------|-------------|---------|
|
|
||||||
| variable_name | 변수 명 | DLV - transaction_id |
|
|
||||||
| variable_type | 변수 유형 | Data Layer Variable |
|
|
||||||
| datalayer_name | DL 변수명 | ecommerce.transaction_id |
|
|
||||||
| default_value | 기본값 | undefined |
|
|
||||||
| used_by | 사용 태그 | GA4 - Event - purchase |
|
|
||||||
|
|
||||||
## Google Sheets Template
|
|
||||||
|
|
||||||
### Quick Setup
|
|
||||||
1. 새 Google Sheets 생성
|
|
||||||
2. 시트 탭 6개 생성 (위 구조대로)
|
|
||||||
3. 헤더 행 고정 (View > Freeze > 1 row)
|
|
||||||
4. 조건부 서식 적용 (Priority별 색상)
|
|
||||||
5. 데이터 유효성 검사 (Dropdown)
|
|
||||||
|
|
||||||
### Dropdown Validations
|
|
||||||
```
|
|
||||||
event_category: ecommerce, engagement, lead_gen, content
|
|
||||||
trigger_type: dataLayer, click, pageview, scroll, timer
|
|
||||||
priority: P1, P2, P3
|
|
||||||
data_type: string, number, boolean, array, object
|
|
||||||
scope: event, user, session
|
|
||||||
```
|
|
||||||
|
|
||||||
### Conditional Formatting
|
|
||||||
```
|
|
||||||
P1: Red background
|
|
||||||
P2: Yellow background
|
|
||||||
P3: Green background
|
|
||||||
```
|
|
||||||
|
|
||||||
## Sample Event Taxonomy
|
|
||||||
|
|
||||||
### E-commerce Events
|
|
||||||
```csv
|
|
||||||
event_name,event_category,trigger_type,trigger_condition,parameters,priority
|
|
||||||
view_item_list,ecommerce,dataLayer,"event equals 'view_item_list'","item_list_id, item_list_name, items",P2
|
|
||||||
view_item,ecommerce,dataLayer,"event equals 'view_item'","currency, value, items",P1
|
|
||||||
add_to_cart,ecommerce,dataLayer,"event equals 'add_to_cart'","currency, value, items",P1
|
|
||||||
begin_checkout,ecommerce,dataLayer,"event equals 'begin_checkout'","currency, value, items, coupon",P1
|
|
||||||
purchase,ecommerce,dataLayer,"event equals 'purchase'","transaction_id, currency, value, items, shipping, tax",P1
|
|
||||||
```
|
|
||||||
|
|
||||||
### Lead Gen Events
|
|
||||||
```csv
|
|
||||||
event_name,event_category,trigger_type,trigger_condition,parameters,priority
|
|
||||||
form_start,lead_gen,dataLayer,"event equals 'form_start'","form_id, form_name",P2
|
|
||||||
form_submit,lead_gen,dataLayer,"event equals 'form_submit'","form_id, form_name, success",P1
|
|
||||||
generate_lead,lead_gen,dataLayer,"event equals 'generate_lead'","currency, value, source",P1
|
|
||||||
```
|
|
||||||
|
|
||||||
## Naming Convention Reference
|
|
||||||
|
|
||||||
→ [naming-conventions.md](naming-conventions.md)
|
|
||||||
|
|
||||||
### Quick Reference
|
|
||||||
| Type | Pattern | Example |
|
|
||||||
|------|---------|---------|
|
|
||||||
| Tag | [Platform] - [Type] - [Event] | GA4 - Event - purchase |
|
|
||||||
| Trigger | [Type] - [Event/Condition] | DL - purchase |
|
|
||||||
| Variable | [Type] - [Name] | DLV - transaction_id |
|
|
||||||
|
|
||||||
## Output Delivery
|
|
||||||
|
|
||||||
### Format Options
|
|
||||||
1. **Google Sheets** (권장): 공유 및 협업 용이
|
|
||||||
2. **Excel (.xlsx)**: 오프라인/보안 요구 시
|
|
||||||
3. **CSV**: 개발팀 연동 시
|
|
||||||
|
|
||||||
### Sharing
|
|
||||||
- Viewer 권한: 마케팅팀, 경영진
|
|
||||||
- Editor 권한: 분석팀, 개발팀
|
|
||||||
- 버전 히스토리 활용
|
|
||||||
|
|
||||||
## Next Phase
|
|
||||||
|
|
||||||
Event Taxonomy 완료 후 → Phase 5: Implementation Guide
|
|
||||||
@@ -1,208 +0,0 @@
|
|||||||
# Phase 5: Implementation Plan & Guide
|
|
||||||
|
|
||||||
분석된 웹사이트/앱의 상태와 타입, 비즈니스 목표에 맞는 태그 설정 순서와 전략, 체크리스트 도출.
|
|
||||||
|
|
||||||
## Objectives
|
|
||||||
|
|
||||||
1. 구현 우선순위 및 순서 결정
|
|
||||||
2. 개발팀용 DataLayer 가이드 작성
|
|
||||||
3. GTM 컨테이너 설정 가이드
|
|
||||||
4. QA 체크리스트 도출
|
|
||||||
|
|
||||||
## Implementation Sequence
|
|
||||||
|
|
||||||
### Standard Sequence
|
|
||||||
```
|
|
||||||
1. Base Setup (Week 1)
|
|
||||||
├── GTM Container 설치
|
|
||||||
├── GA4 Configuration Tag
|
|
||||||
└── 기본 page_view 확인
|
|
||||||
|
|
||||||
2. DataLayer Implementation (Week 1-2)
|
|
||||||
├── 페이지 데이터 (pageType, userId 등)
|
|
||||||
└── E-commerce / Lead Gen 이벤트
|
|
||||||
|
|
||||||
3. Core Events (Week 2)
|
|
||||||
├── P1 이벤트 태그 설정
|
|
||||||
├── 트리거 구성
|
|
||||||
└── 변수 설정
|
|
||||||
|
|
||||||
4. Platform Tags (Week 2-3)
|
|
||||||
├── Google Ads Conversion
|
|
||||||
├── Meta Pixel
|
|
||||||
└── Kakao Pixel
|
|
||||||
|
|
||||||
5. QA & Launch (Week 3)
|
|
||||||
├── Preview 모드 테스트
|
|
||||||
├── 데이터 검증
|
|
||||||
└── Production 배포
|
|
||||||
```
|
|
||||||
|
|
||||||
### E-commerce Priority
|
|
||||||
```
|
|
||||||
P1: purchase → begin_checkout → add_to_cart → view_item
|
|
||||||
P2: view_item_list → add_to_wishlist → search
|
|
||||||
P3: select_item → scroll → video
|
|
||||||
```
|
|
||||||
|
|
||||||
### Lead Gen Priority
|
|
||||||
```
|
|
||||||
P1: generate_lead → form_submit
|
|
||||||
P2: form_start → page_view (특정 페이지)
|
|
||||||
P3: cta_click → scroll → video
|
|
||||||
```
|
|
||||||
|
|
||||||
## Developer Guide Template
|
|
||||||
|
|
||||||
### DataLayer Implementation Guide
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# DataLayer 구현 가이드
|
|
||||||
|
|
||||||
## 1. 기본 설정
|
|
||||||
|
|
||||||
### GTM 스니펫 이전 dataLayer 초기화
|
|
||||||
```html
|
|
||||||
<script>
|
|
||||||
window.dataLayer = window.dataLayer || [];
|
|
||||||
</script>
|
|
||||||
<!-- Google Tag Manager -->
|
|
||||||
<script>...</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
### 페이지 로드 시 기본 데이터
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'page_data',
|
|
||||||
'page': {
|
|
||||||
'type': '[page_type]', // home, category, product, cart, checkout, thankyou
|
|
||||||
'name': '[page_name]',
|
|
||||||
'language': 'ko'
|
|
||||||
},
|
|
||||||
'user': {
|
|
||||||
'status': '[logged_in|logged_out]',
|
|
||||||
'id': '[hashed_user_id]', // SHA256 해시, 로그인 시에만
|
|
||||||
'type': '[new|returning]'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. 이벤트별 구현
|
|
||||||
|
|
||||||
### [이벤트명]
|
|
||||||
**발화 시점**: [설명]
|
|
||||||
**필수 파라미터**: [목록]
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({ ecommerce: null }); // E-commerce 이벤트 시 필수
|
|
||||||
dataLayer.push({
|
|
||||||
'event': '[event_name]',
|
|
||||||
// 파라미터...
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3. 테스트 방법
|
|
||||||
1. Chrome DevTools Console에서 dataLayer 확인
|
|
||||||
2. GTM Preview 모드에서 이벤트 확인
|
|
||||||
3. GA4 DebugView에서 수신 확인
|
|
||||||
```
|
|
||||||
|
|
||||||
## GTM Configuration Guide
|
|
||||||
|
|
||||||
### Container Setup Checklist
|
|
||||||
|
|
||||||
- [ ] Container ID 확인
|
|
||||||
- [ ] Web Container 타입 선택
|
|
||||||
- [ ] 환경(Dev/Stg/Prod) 설정
|
|
||||||
|
|
||||||
### Built-in Variables 활성화
|
|
||||||
|
|
||||||
```
|
|
||||||
✅ Page URL, Page Path, Page Hostname, Referrer
|
|
||||||
✅ Click Element, Click Classes, Click ID, Click URL, Click Text
|
|
||||||
✅ Form Element, Form Classes, Form ID, Form URL, Form Text
|
|
||||||
✅ Scroll Depth Threshold, Scroll Depth Units, Scroll Direction
|
|
||||||
✅ Video Provider, Video Status, Video URL, Video Title, Video Duration, Video Percent
|
|
||||||
```
|
|
||||||
|
|
||||||
### Folder Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
📁 01. Configuration
|
|
||||||
📁 02. GA4 Events
|
|
||||||
📁 03. Google Ads
|
|
||||||
📁 04. Meta Pixel
|
|
||||||
📁 05. Kakao Pixel
|
|
||||||
📁 06. Utilities
|
|
||||||
📁 99. Deprecated
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tag Setup Order
|
|
||||||
|
|
||||||
```
|
|
||||||
1. Constants (Measurement IDs, Pixel IDs)
|
|
||||||
2. DataLayer Variables
|
|
||||||
3. Custom JavaScript Variables
|
|
||||||
4. Triggers (Event-based)
|
|
||||||
5. Blocking Triggers (Internal traffic)
|
|
||||||
6. Configuration Tags
|
|
||||||
7. Event Tags
|
|
||||||
```
|
|
||||||
|
|
||||||
## QA Checklist
|
|
||||||
|
|
||||||
→ 상세 체크리스트: [qa-checklist.md](qa-checklist.md)
|
|
||||||
|
|
||||||
### Pre-Launch Quick Check
|
|
||||||
|
|
||||||
#### DataLayer
|
|
||||||
- [ ] dataLayer가 GTM 스니펫 이전에 초기화됨
|
|
||||||
- [ ] 페이지 로드 시 기본 데이터 push됨
|
|
||||||
- [ ] 숫자 값이 Number 타입으로 전송됨
|
|
||||||
- [ ] ecommerce 이벤트 전 null push됨
|
|
||||||
|
|
||||||
#### Tags
|
|
||||||
- [ ] 모든 P1 이벤트 태그 설정됨
|
|
||||||
- [ ] 트리거 조건 정확함
|
|
||||||
- [ ] 변수 값 정확히 매핑됨
|
|
||||||
|
|
||||||
#### Testing
|
|
||||||
- [ ] Preview 모드에서 모든 태그 발화 확인
|
|
||||||
- [ ] GA4 DebugView에서 데이터 수신 확인
|
|
||||||
- [ ] Network 탭에서 요청 확인
|
|
||||||
|
|
||||||
#### Cross-check
|
|
||||||
- [ ] 데스크톱 Chrome 테스트
|
|
||||||
- [ ] 모바일 Safari 테스트
|
|
||||||
- [ ] Internal traffic 필터 작동
|
|
||||||
|
|
||||||
## Common Implementation Issues
|
|
||||||
|
|
||||||
| Issue | Solution |
|
|
||||||
|-------|----------|
|
|
||||||
| dataLayer not defined | GTM 스니펫 이전에 초기화 |
|
|
||||||
| 숫자가 문자열로 전송 | 따옴표 제거, parseInt/parseFloat |
|
|
||||||
| 이벤트 중복 발화 | 트리거 조건 검토, 페이지 상태 확인 |
|
|
||||||
| 태그 미발화 | Preview에서 트리거 조건 디버깅 |
|
|
||||||
| 데이터 불일치 | DL 변수 경로 확인, 대소문자 확인 |
|
|
||||||
|
|
||||||
## Handoff Checklist
|
|
||||||
|
|
||||||
### To Development Team
|
|
||||||
- [ ] DataLayer 구현 가이드 전달
|
|
||||||
- [ ] 이벤트 택소노미 시트 공유
|
|
||||||
- [ ] Q&A 세션 완료
|
|
||||||
|
|
||||||
### To Marketing Team
|
|
||||||
- [ ] 측정 가능한 이벤트 목록 공유
|
|
||||||
- [ ] GA4 보고서 접근 권한 확인
|
|
||||||
- [ ] 전환 설정 완료 확인
|
|
||||||
|
|
||||||
### Documentation
|
|
||||||
- [ ] Tagging Plan 최종 버전 저장
|
|
||||||
- [ ] GTM 컨테이너 버전 기록
|
|
||||||
- [ ] Notion에 모든 문서 업로드
|
|
||||||
|
|
||||||
## Next Phase
|
|
||||||
|
|
||||||
구현 완료 후 → Phase 6: Progressive Audit
|
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
# Platform Event Mapping Reference
|
|
||||||
|
|
||||||
GA4, Google Ads, Meta Pixel, Kakao Pixel 간 이벤트 매핑.
|
|
||||||
|
|
||||||
## E-commerce Events
|
|
||||||
|
|
||||||
| User Action | GA4 | Meta | Kakao | Google Ads |
|
|
||||||
|-------------|-----|------|-------|------------|
|
|
||||||
| 상품 목록 조회 | view_item_list | ViewContent | viewContent | - |
|
|
||||||
| 상품 상세 조회 | view_item | ViewContent | viewContent | - |
|
|
||||||
| 상품 검색 | search | Search | search | - |
|
|
||||||
| 장바구니 담기 | add_to_cart | AddToCart | addToCart | - |
|
|
||||||
| 위시리스트 | add_to_wishlist | AddToWishlist | addToWishlist | - |
|
|
||||||
| 결제 시작 | begin_checkout | InitiateCheckout | beginCheckout | - |
|
|
||||||
| 배송정보 입력 | add_shipping_info | - | - | - |
|
|
||||||
| 결제정보 입력 | add_payment_info | AddPaymentInfo | addPaymentInfo | - |
|
|
||||||
| 구매 완료 | purchase | Purchase | purchase | purchase |
|
|
||||||
|
|
||||||
## Lead Gen Events
|
|
||||||
|
|
||||||
| User Action | GA4 | Meta | Kakao | Google Ads |
|
|
||||||
|-------------|-----|------|-------|------------|
|
|
||||||
| 회원가입 | sign_up | CompleteRegistration | completeRegistration | sign_up |
|
|
||||||
| 로그인 | login | - | login | - |
|
|
||||||
| 리드 생성 | generate_lead | Lead | participation | submit_lead_form |
|
|
||||||
|
|
||||||
## Engagement Events
|
|
||||||
|
|
||||||
| User Action | GA4 | Meta | Kakao | Google Ads |
|
|
||||||
|-------------|-----|------|-------|------------|
|
|
||||||
| 페이지 조회 | page_view | PageView | pageView | page_view |
|
|
||||||
| 검색 | search | Search | search | - |
|
|
||||||
| 공유 | share | - | - | - |
|
|
||||||
|
|
||||||
## Parameter Transformation
|
|
||||||
|
|
||||||
### GA4 → Meta
|
|
||||||
```javascript
|
|
||||||
// GA4 items[] → Meta content_ids[]
|
|
||||||
const contentIds = items.map(item => item.item_id);
|
|
||||||
|
|
||||||
// Meta Purchase
|
|
||||||
fbq('track', 'Purchase', {
|
|
||||||
content_ids: contentIds,
|
|
||||||
content_type: 'product',
|
|
||||||
value: ecommerce.value,
|
|
||||||
currency: 'KRW',
|
|
||||||
num_items: items.length
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### GA4 → Kakao
|
|
||||||
```javascript
|
|
||||||
// GA4 items[] → Kakao products[]
|
|
||||||
const products = items.map(item => ({
|
|
||||||
id: item.item_id,
|
|
||||||
name: item.item_name,
|
|
||||||
price: item.price,
|
|
||||||
quantity: item.quantity
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Kakao purchase
|
|
||||||
kakaoPixel('PIXEL_ID').purchase({
|
|
||||||
total_price: ecommerce.value,
|
|
||||||
currency: 'KRW',
|
|
||||||
products: products
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## GTM Variables
|
|
||||||
|
|
||||||
### CJS - Item IDs for Meta
|
|
||||||
```javascript
|
|
||||||
function() {
|
|
||||||
var items = {{DLV - ecommerce.items}} || [];
|
|
||||||
return items.map(function(item) {
|
|
||||||
return item.item_id;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### CJS - Products for Kakao
|
|
||||||
```javascript
|
|
||||||
function() {
|
|
||||||
var items = {{DLV - ecommerce.items}} || [];
|
|
||||||
return items.map(function(item) {
|
|
||||||
return {
|
|
||||||
id: item.item_id,
|
|
||||||
name: item.item_name,
|
|
||||||
price: item.price,
|
|
||||||
quantity: item.quantity
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Deduplication
|
|
||||||
|
|
||||||
### Event ID Pattern
|
|
||||||
```javascript
|
|
||||||
var eventId = 'evt_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
|
|
||||||
|
|
||||||
// Client-side
|
|
||||||
fbq('track', 'Purchase', {...}, {eventID: eventId});
|
|
||||||
|
|
||||||
// Server-side (CAPI)
|
|
||||||
// 동일한 eventId 사용 → Meta 자동 중복 제거
|
|
||||||
```
|
|
||||||
|
|
||||||
## Platform-specific Notes
|
|
||||||
|
|
||||||
### Meta Pixel
|
|
||||||
- content_type: 'product' (상품) / 'product_group' (변형)
|
|
||||||
- currency: ISO 4217 필수
|
|
||||||
- value: 숫자 (소수점 가능)
|
|
||||||
|
|
||||||
### Kakao Pixel
|
|
||||||
- Server-side 미지원 (Client-only)
|
|
||||||
- products[]: 최대 10개 권장
|
|
||||||
- total_price: 숫자
|
|
||||||
|
|
||||||
### Google Ads
|
|
||||||
- Enhanced Conversions 권장
|
|
||||||
- transaction_id 필수 (중복 제거용)
|
|
||||||
- value: KRW 정수
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
# GTM Implementation QA Checklist
|
|
||||||
|
|
||||||
태깅 구현 품질 검증 체크리스트.
|
|
||||||
|
|
||||||
## 1. Pre-Implementation
|
|
||||||
|
|
||||||
### Documentation
|
|
||||||
- [ ] Tagging Plan 승인 완료
|
|
||||||
- [ ] DataLayer 스키마 개발팀 공유
|
|
||||||
- [ ] 이벤트 택소노미 합의 완료
|
|
||||||
|
|
||||||
### Access
|
|
||||||
- [ ] GTM 컨테이너 접근 권한
|
|
||||||
- [ ] GA4 속성 접근 권한
|
|
||||||
- [ ] 광고 플랫폼 접근 권한
|
|
||||||
|
|
||||||
### Tools
|
|
||||||
- [ ] GTM Preview 모드 정상
|
|
||||||
- [ ] GA4 DebugView 활성화
|
|
||||||
- [ ] Chrome DevTools 준비
|
|
||||||
|
|
||||||
## 2. DataLayer Validation
|
|
||||||
|
|
||||||
### Base Setup
|
|
||||||
- [ ] GTM 스니펫 이전 dataLayer 초기화
|
|
||||||
- [ ] 페이지 로드 시 기본 데이터 push
|
|
||||||
- [ ] pageType, userId 등 기본 변수 존재
|
|
||||||
|
|
||||||
### Data Types
|
|
||||||
- [ ] 숫자 값이 Number 타입
|
|
||||||
- [ ] 금액에 통화 코드 포함 (KRW)
|
|
||||||
- [ ] transaction_id 유니크
|
|
||||||
|
|
||||||
### E-commerce
|
|
||||||
- [ ] ecommerce: null 선행 push
|
|
||||||
- [ ] items[] 배열 구조 정확
|
|
||||||
- [ ] 필수 파라미터 완비
|
|
||||||
|
|
||||||
### Console Check
|
|
||||||
```javascript
|
|
||||||
console.log(window.dataLayer);
|
|
||||||
dataLayer.filter(e => e.event === 'purchase');
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3. Tag Firing
|
|
||||||
|
|
||||||
### GA4
|
|
||||||
| Tag | Trigger | Status |
|
|
||||||
|-----|---------|--------|
|
|
||||||
| Config | All Pages | [ ] |
|
|
||||||
| view_item | Product page | [ ] |
|
|
||||||
| add_to_cart | Add button | [ ] |
|
|
||||||
| begin_checkout | Checkout start | [ ] |
|
|
||||||
| purchase | Thank you | [ ] |
|
|
||||||
|
|
||||||
### Google Ads
|
|
||||||
| Conversion | Trigger | Status |
|
|
||||||
|------------|---------|--------|
|
|
||||||
| Purchase | DL - purchase | [ ] |
|
|
||||||
| Lead | DL - generate_lead | [ ] |
|
|
||||||
|
|
||||||
### Meta Pixel
|
|
||||||
| Event | Trigger | Status |
|
|
||||||
|-------|---------|--------|
|
|
||||||
| PageView | All Pages | [ ] |
|
|
||||||
| ViewContent | Product | [ ] |
|
|
||||||
| AddToCart | Add | [ ] |
|
|
||||||
| Purchase | Thank you | [ ] |
|
|
||||||
|
|
||||||
### Kakao Pixel
|
|
||||||
| Event | Trigger | Status |
|
|
||||||
|-------|---------|--------|
|
|
||||||
| pageView | All Pages | [ ] |
|
|
||||||
| purchase | Thank you | [ ] |
|
|
||||||
|
|
||||||
## 4. Network Validation
|
|
||||||
|
|
||||||
### Endpoints
|
|
||||||
```
|
|
||||||
GA4: google-analytics.com/g/collect
|
|
||||||
GAds: googleads.g.doubleclick.net/pagead/conversion/
|
|
||||||
Meta: facebook.com/tr/
|
|
||||||
```
|
|
||||||
|
|
||||||
### Check Points
|
|
||||||
- [ ] 요청 전송됨
|
|
||||||
- [ ] 파라미터 정확
|
|
||||||
- [ ] 응답 성공 (200/204)
|
|
||||||
|
|
||||||
## 5. Cross-browser Testing
|
|
||||||
|
|
||||||
### Desktop
|
|
||||||
- [ ] Chrome
|
|
||||||
- [ ] Safari
|
|
||||||
- [ ] Firefox
|
|
||||||
- [ ] Edge
|
|
||||||
|
|
||||||
### Mobile
|
|
||||||
- [ ] iOS Safari
|
|
||||||
- [ ] iOS Chrome
|
|
||||||
- [ ] Android Chrome
|
|
||||||
|
|
||||||
## 6. Data Validation (Platform)
|
|
||||||
|
|
||||||
### GA4
|
|
||||||
- [ ] Realtime 보고서 이벤트 표시
|
|
||||||
- [ ] 파라미터 정확히 수집
|
|
||||||
- [ ] E-commerce 보고서 정확
|
|
||||||
|
|
||||||
### Google Ads
|
|
||||||
- [ ] 전환 액션 데이터 유입
|
|
||||||
- [ ] 전환 값 정확
|
|
||||||
|
|
||||||
### Meta
|
|
||||||
- [ ] Events Manager 수신 확인
|
|
||||||
- [ ] Event match quality 확인
|
|
||||||
|
|
||||||
## 7. Edge Cases
|
|
||||||
|
|
||||||
- [ ] 빈 장바구니 결제 시작 처리
|
|
||||||
- [ ] 0개 구매 처리
|
|
||||||
- [ ] 쿠폰 없는 구매
|
|
||||||
- [ ] 게스트 체크아웃
|
|
||||||
- [ ] 새로고침 시 중복 방지
|
|
||||||
- [ ] 뒤로가기 시 처리
|
|
||||||
|
|
||||||
## 8. Performance & Privacy
|
|
||||||
|
|
||||||
### Performance
|
|
||||||
- [ ] 태그 로딩이 렌더링 차단 안 함
|
|
||||||
- [ ] 비동기 로딩
|
|
||||||
|
|
||||||
### Privacy
|
|
||||||
- [ ] 동의 없이 태그 미발화 (CMP 시)
|
|
||||||
- [ ] PII 직접 수집 없음
|
|
||||||
|
|
||||||
## Sign-off
|
|
||||||
|
|
||||||
| Role | Name | Date | ✓ |
|
|
||||||
|------|------|------|---|
|
|
||||||
| QA Lead | | | |
|
|
||||||
| Analytics Lead | | | |
|
|
||||||
| Dev Lead | | | |
|
|
||||||
|
|
||||||
## Issues Log
|
|
||||||
|
|
||||||
| # | Issue | Severity | Status |
|
|
||||||
|---|-------|----------|--------|
|
|
||||||
| 1 | | High/Med/Low | Open/Resolved |
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
# Server-side GTM Guide
|
|
||||||
|
|
||||||
sGTM 아키텍처 옵션 및 설정 가이드.
|
|
||||||
|
|
||||||
## Why Server-side GTM?
|
|
||||||
|
|
||||||
| Benefit | Description |
|
|
||||||
|---------|-------------|
|
|
||||||
| Data Control | 클라이언트 → 서버 → 벤더 흐름 제어 |
|
|
||||||
| Privacy | PII 필터링, 서버에서 처리 |
|
|
||||||
| Cookie Duration | 1st-party cookie (최대 2년) |
|
|
||||||
| Performance | 클라이언트 JS 감소 |
|
|
||||||
| Reliability | Ad blocker 영향 최소화 |
|
|
||||||
|
|
||||||
## Architecture Options
|
|
||||||
|
|
||||||
### Option 1: GCP Cloud Run
|
|
||||||
```
|
|
||||||
Browser → Your Domain (1st-party) → GCP Cloud Run → GA4/Ads/Meta
|
|
||||||
```
|
|
||||||
- **Pros**: 완전한 제어, GCP 통합
|
|
||||||
- **Cons**: GCP 전문 지식 필요
|
|
||||||
- **Cost**: Low ~$20, Medium ~$100, High $200+/월
|
|
||||||
|
|
||||||
### Option 2: Stape.io (Managed)
|
|
||||||
```
|
|
||||||
Browser → Stape CDN → Stape Server → GA4/Ads/Meta
|
|
||||||
```
|
|
||||||
- **Pros**: 간편 설정 (10분), 관리형, 한국 리전
|
|
||||||
- **Cons**: 월정액, 벤더 종속
|
|
||||||
- **Cost**: Starter $20, Business $50, Scale $150/월
|
|
||||||
|
|
||||||
### Option 3: Google Tag Gateway
|
|
||||||
```
|
|
||||||
Browser → Google Gateway → Google Cloud (Managed) → GA4/Ads
|
|
||||||
```
|
|
||||||
- **Pros**: Google 관리형, 무료(제한적)
|
|
||||||
- **Cons**: Google 태그만 지원, 제한된 커스터마이징
|
|
||||||
|
|
||||||
## Selection Guide
|
|
||||||
|
|
||||||
| Requirement | Recommendation |
|
|
||||||
|-------------|----------------|
|
|
||||||
| Google 태그만 | Tag Gateway |
|
|
||||||
| 빠른 구현 | Stape.io |
|
|
||||||
| 완전한 제어 | GCP Cloud Run |
|
|
||||||
| Third-party 태그 (Meta 등) | Stape 또는 GCP |
|
|
||||||
|
|
||||||
## Client Configuration
|
|
||||||
|
|
||||||
### Web Container 설정
|
|
||||||
```javascript
|
|
||||||
gtag('config', 'G-XXXXXXXXXX', {
|
|
||||||
'server_container_url': 'https://gtm.yourdomain.com'
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### GTM GA4 Configuration Tag
|
|
||||||
```
|
|
||||||
Advanced Settings:
|
|
||||||
Server container URL: https://gtm.yourdomain.com
|
|
||||||
```
|
|
||||||
|
|
||||||
## Stape Quick Setup
|
|
||||||
|
|
||||||
1. **계정 생성**: stape.io
|
|
||||||
2. **Container 생성**: Region = Seoul (asia-northeast3)
|
|
||||||
3. **Custom Domain 연결**
|
|
||||||
```
|
|
||||||
DNS: gtm.example.com CNAME [stape-provided-address]
|
|
||||||
```
|
|
||||||
4. **GTM Server Container ID 연결**
|
|
||||||
5. **Web Container 수정**: server_container_url 추가
|
|
||||||
|
|
||||||
## Server Tags
|
|
||||||
|
|
||||||
### GA4 Tag
|
|
||||||
```
|
|
||||||
Measurement ID: G-XXXXXXXXXX
|
|
||||||
Event Name: {{Event Name}}
|
|
||||||
Event Parameters: {{Event Data}}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Google Ads Conversion
|
|
||||||
```
|
|
||||||
Conversion ID: AW-XXXXXXXXX
|
|
||||||
Conversion Label: [Label]
|
|
||||||
Enhanced Conversions: Enabled
|
|
||||||
```
|
|
||||||
|
|
||||||
### Meta Conversions API
|
|
||||||
```
|
|
||||||
Pixel ID: [ID]
|
|
||||||
API Access Token: [Token]
|
|
||||||
Event Name: {{Event Name}}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
1. **Preview Mode**: GTM Server Container → Preview
|
|
||||||
2. **Validation**:
|
|
||||||
- Client → Server 요청 도달
|
|
||||||
- Server → Platform 전송 확인
|
|
||||||
- Cookie 설정 확인 (1st-party)
|
|
||||||
- Latency < 200ms
|
|
||||||
|
|
||||||
## Common Issues
|
|
||||||
|
|
||||||
| Issue | Solution |
|
|
||||||
|-------|----------|
|
|
||||||
| 요청 미도달 | CORS, Custom domain 확인 |
|
|
||||||
| Cookie 미설정 | Same-site 정책, 도메인 확인 |
|
|
||||||
| Timeout | 리전 최적화, 스케일링 |
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# Skill metadata (extracted from SKILL.md frontmatter)
|
|
||||||
|
|
||||||
name: gtm-guardian
|
|
||||||
description: |
|
|
||||||
Google Tag Manager 태깅 전략 수립부터 구현까지 7단계 워크플로우를 지원하는 SMART Tool.
|
|
||||||
|
|
||||||
Triggers:
|
|
||||||
- GTM 태깅 계획, Tagging Plan 작성, 이벤트 설계
|
|
||||||
- DataLayer 스키마 설계, dataLayer 구현 가이드
|
|
||||||
- 사용자 행동 분석, User Behaviour Modeling, KPI 정의
|
|
||||||
- Event Taxonomy, 이벤트 택소노미, 이벤트 명명 규칙
|
|
||||||
- GTM 구현 가이드, 태그 설정 체크리스트
|
|
||||||
- Server-side GTM, sGTM, Stape, Google Tag Gateway
|
|
||||||
- GA4 이벤트, Meta Pixel, Kakao Pixel, Google Ads 전환 추적
|
|
||||||
|
|
||||||
# Optional fields
|
|
||||||
|
|
||||||
# triggers: [] # TODO: Extract from description
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
event_name,event_category,trigger_type,trigger_condition,parameters,custom_dimensions,custom_metrics,ga4_mapping,meta_mapping,kakao_mapping,gads_mapping,priority,notes
|
|
||||||
page_view,engagement,pageview,All Pages,-,-,-,page_view (auto),PageView,pageView,-,P1,자동 수집
|
|
||||||
view_item,ecommerce,dataLayer,event equals 'view_item',"items[], value, currency",page_type,-,view_item,ViewContent,viewContent,-,P1,상품 상세 조회
|
|
||||||
view_item_list,ecommerce,dataLayer,event equals 'view_item_list',"item_list_id, item_list_name, items[]",-,-,view_item_list,ViewContent,viewContent,-,P2,상품 목록 조회
|
|
||||||
select_item,ecommerce,dataLayer,event equals 'select_item',"item_list_id, items[]",-,-,select_item,-,-,-,P3,목록에서 상품 선택
|
|
||||||
add_to_cart,ecommerce,dataLayer,event equals 'add_to_cart',"items[], value, currency",-,-,add_to_cart,AddToCart,addToCart,-,P1,장바구니 담기
|
|
||||||
remove_from_cart,ecommerce,dataLayer,event equals 'remove_from_cart',"items[], value, currency",-,-,remove_from_cart,-,-,-,P2,장바구니 삭제
|
|
||||||
view_cart,ecommerce,dataLayer,event equals 'view_cart',"items[], value, currency",-,-,view_cart,-,-,-,P2,장바구니 조회
|
|
||||||
add_to_wishlist,ecommerce,dataLayer,event equals 'add_to_wishlist',"items[], value, currency",-,wishlist_adds,add_to_wishlist,AddToWishlist,addToWishlist,-,P3,위시리스트 추가
|
|
||||||
begin_checkout,ecommerce,dataLayer,event equals 'begin_checkout',"items[], value, currency, coupon",-,-,begin_checkout,InitiateCheckout,beginCheckout,-,P1,결제 시작
|
|
||||||
add_shipping_info,ecommerce,dataLayer,event equals 'add_shipping_info',"items[], value, currency, shipping_tier",-,-,add_shipping_info,-,-,-,P2,배송정보 입력
|
|
||||||
add_payment_info,ecommerce,dataLayer,event equals 'add_payment_info',"items[], value, currency, payment_type",-,-,add_payment_info,AddPaymentInfo,addPaymentInfo,-,P2,결제정보 입력
|
|
||||||
purchase,ecommerce,dataLayer,event equals 'purchase',"transaction_id, items[], value, currency, tax, shipping, coupon",payment_method,-,purchase,Purchase,purchase,purchase,P1,구매 완료
|
|
||||||
refund,ecommerce,dataLayer,event equals 'refund',"transaction_id, items[], value, currency",-,-,refund,-,-,-,P2,환불
|
|
||||||
login,engagement,dataLayer,event equals 'login',method,-,-,login,-,login,-,P2,로그인
|
|
||||||
sign_up,engagement,dataLayer,event equals 'sign_up',method,-,-,sign_up,CompleteRegistration,completeRegistration,sign_up,P2,회원가입
|
|
||||||
search,engagement,dataLayer,event equals 'search',"search_term, results_count",-,-,search,Search,search,-,P2,검색
|
|
||||||
generate_lead,lead_gen,dataLayer,event equals 'generate_lead',"value, currency, lead_source",-,-,generate_lead,Lead,participation,submit_lead_form,P1,리드 생성
|
|
||||||
form_start,lead_gen,dataLayer,event equals 'form_start',"form_id, form_name",-,form_starts,custom,-,-,-,P2,폼 시작
|
|
||||||
form_submit,lead_gen,dataLayer,event equals 'form_submit',"form_id, form_name, success",-,-,custom,Lead,participation,-,P1,폼 제출
|
|
||||||
share,engagement,dataLayer,event equals 'share',"method, content_type, item_id",-,-,share,-,-,-,P3,공유
|
|
||||||
cta_click,engagement,click,Click matches CTA selector,"cta_id, cta_text, cta_location",-,-,custom,-,-,-,P3,CTA 클릭
|
|
||||||
video_start,engagement,dataLayer,event equals 'video_start',"video_title, video_id, video_duration",-,-,custom,-,-,-,P3,비디오 시작
|
|
||||||
video_complete,engagement,dataLayer,event equals 'video_complete',"video_title, video_id",-,-,custom,-,-,-,P3,비디오 완료
|
|
||||||
scroll_depth,engagement,scroll,Scroll 90%,percent,-,-,scroll (auto),-,-,-,P3,스크롤 깊이
|
|
||||||
|
@@ -1,147 +0,0 @@
|
|||||||
# [Project Name] Tagging Plan v1.0
|
|
||||||
|
|
||||||
## Document Information
|
|
||||||
|
|
||||||
| Field | Value |
|
|
||||||
|-------|-------|
|
|
||||||
| Project | [프로젝트명] |
|
|
||||||
| Client | [클라이언트명] |
|
|
||||||
| Website/App | [URL] |
|
|
||||||
| Version | 1.0 |
|
|
||||||
| Last Updated | YYYY-MM-DD |
|
|
||||||
| Author | [작성자] |
|
|
||||||
| Status | Draft / Review / Approved |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. Executive Summary
|
|
||||||
|
|
||||||
### 1.1 Measurement Objectives
|
|
||||||
| Priority | Objective | KPI | Target |
|
|
||||||
|----------|-----------|-----|--------|
|
|
||||||
| P1 | | | |
|
|
||||||
| P2 | | | |
|
|
||||||
| P3 | | | |
|
|
||||||
|
|
||||||
### 1.2 Key Conversions
|
|
||||||
| Conversion | Type | Value | Platform |
|
|
||||||
|------------|------|-------|----------|
|
|
||||||
| | Hard/Soft | | GA4, GAds, Meta |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Event Specification
|
|
||||||
|
|
||||||
### 2.1 GA4 Recommended Events
|
|
||||||
| Event | Trigger | Required Params | Status |
|
|
||||||
|-------|---------|-----------------|--------|
|
|
||||||
| page_view | All pages | - | ✅ |
|
|
||||||
| view_item | Product page | items[], value, currency | |
|
|
||||||
| add_to_cart | Add button | items[], value, currency | |
|
|
||||||
| begin_checkout | Checkout start | items[], value, currency | |
|
|
||||||
| purchase | Thank you | transaction_id, items[], value, currency | |
|
|
||||||
|
|
||||||
### 2.2 Custom Events
|
|
||||||
| Event | Purpose | Trigger | Parameters |
|
|
||||||
|-------|---------|---------|------------|
|
|
||||||
| | | | |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. DataLayer Specification
|
|
||||||
|
|
||||||
### 3.1 Page Load Data
|
|
||||||
```javascript
|
|
||||||
dataLayer.push({
|
|
||||||
'event': 'page_data',
|
|
||||||
'page': {
|
|
||||||
'type': '[page_type]',
|
|
||||||
'name': '[page_name]'
|
|
||||||
},
|
|
||||||
'user': {
|
|
||||||
'status': '[logged_in|logged_out]',
|
|
||||||
'id': '[hashed_user_id]'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3.2 E-commerce Events
|
|
||||||
→ See datalayer-schema.md
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Tag Configuration
|
|
||||||
|
|
||||||
### 4.1 GA4 Tags
|
|
||||||
| Tag Name | Trigger | Variables |
|
|
||||||
|----------|---------|-----------|
|
|
||||||
| GA4 - Config - Main | All Pages | Const - GA4 ID |
|
|
||||||
| GA4 - Event - [event] | DL - [event] | DLV - ecommerce.* |
|
|
||||||
|
|
||||||
### 4.2 Google Ads Tags
|
|
||||||
| Tag Name | Conversion ID | Label | Trigger |
|
|
||||||
|----------|---------------|-------|---------|
|
|
||||||
| | | | |
|
|
||||||
|
|
||||||
### 4.3 Meta Pixel Tags
|
|
||||||
| Tag Name | Event | Trigger |
|
|
||||||
|----------|-------|---------|
|
|
||||||
| Meta - PageView | PageView | All Pages |
|
|
||||||
| | | |
|
|
||||||
|
|
||||||
### 4.4 Kakao Pixel Tags
|
|
||||||
| Tag Name | Event | Trigger |
|
|
||||||
|----------|-------|---------|
|
|
||||||
| | | |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. Custom Dimensions & Metrics
|
|
||||||
|
|
||||||
### Custom Dimensions
|
|
||||||
| Name | Scope | Parameter | Values |
|
|
||||||
|------|-------|-----------|--------|
|
|
||||||
| | User/Event | | |
|
|
||||||
|
|
||||||
### Custom Metrics
|
|
||||||
| Name | Unit | Event Source |
|
|
||||||
|------|------|--------------|
|
|
||||||
| | Count/Currency | |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. Platform Mapping
|
|
||||||
|
|
||||||
| GA4 Event | Meta | Kakao | Google Ads |
|
|
||||||
|-----------|------|-------|------------|
|
|
||||||
| view_item | ViewContent | viewContent | - |
|
|
||||||
| add_to_cart | AddToCart | addToCart | - |
|
|
||||||
| purchase | Purchase | purchase | purchase |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. Implementation Timeline
|
|
||||||
|
|
||||||
| Phase | Task | Owner | Due | Status |
|
|
||||||
|-------|------|-------|-----|--------|
|
|
||||||
| 1 | DataLayer 구현 | Dev | | ☐ |
|
|
||||||
| 2 | GTM 태그 설정 | Analytics | | ☐ |
|
|
||||||
| 3 | QA 테스트 | QA | | ☐ |
|
|
||||||
| 4 | 프로덕션 배포 | Dev | | ☐ |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. QA Checklist
|
|
||||||
→ See qa-checklist.md
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Appendix
|
|
||||||
|
|
||||||
### A. Naming Conventions
|
|
||||||
→ See naming-conventions.md
|
|
||||||
|
|
||||||
### B. Change Log
|
|
||||||
| Version | Date | Author | Changes |
|
|
||||||
|---------|------|--------|---------|
|
|
||||||
| 1.0 | | | Initial version |
|
|
||||||
Reference in New Issue
Block a user