Files
our-claude-skills/custom-skills/60-gtm-audit/code/docs/common_issues.md
Andrew Yim f8b61e6745 docs(gtm): add old vs new variable comparison, les subdomain note
- Two-variable comparison table (Path vs URL based)
- Gotcha: new subdomain requires updating 14+ regex rules
- /timesale/, /campaign/ marked as placeholder paths

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 01:35:25 +09:00

9.7 KiB

Common GTM Issues & Fixes

Container Issues

GTM Not Firing

Symptoms: No GTM requests in network tab Causes:

  1. Script blocked by ad blocker
  2. Script placed after closing body tag
  3. JavaScript error before GTM loads
  4. Consent management blocking GTM

Fix:

<!-- Place immediately after opening <head> tag -->
<script>(function(w,d,s,l,i){...})(window,document,'script','dataLayer','GTM-XXXXXX');</script>

Multiple Containers Conflict

Symptoms: Duplicate events, inconsistent data Causes:

  1. Legacy container not removed
  2. Different teams installed separate containers
  3. Theme/plugin auto-installed GTM

Fix:

  1. Audit all containers in source
  2. Consolidate to single container
  3. Use GTM environments for staging/prod

Container ID Mismatch

Symptoms: Tags not firing, wrong property receiving data Causes:

  1. Dev/staging container on production
  2. Copy-paste error during installation

Fix: Verify container ID matches GTM account


DataLayer Issues

DataLayer Not Initialized

Symptoms: First push events lost Code Error:

// Wrong - GTM loads before dataLayer exists
<script>GTM snippet</script>
dataLayer.push({...});

Fix:

// Correct - Initialize dataLayer first
<script>window.dataLayer = window.dataLayer || [];</script>
<script>GTM snippet</script>

Case Sensitivity Issues

Symptoms: Triggers not matching Example:

// DataLayer pushes "AddToCart"
dataLayer.push({ event: "AddToCart" });

// But GTM trigger looks for "addToCart" - won't match!

Fix: Standardize event naming (recommend lowercase with underscores)

Wrong Data Types

Symptoms: Calculations wrong in GA4, missing data Example:

// Wrong - price as string
dataLayer.push({ ecommerce: { value: "29.99" }});

// Correct - price as number
dataLayer.push({ ecommerce: { value: 29.99 }});

Timing Issues

Symptoms: Events fire before data available Cause: DataLayer push happens after tag fires

Fix: Use "Custom Event" trigger instead of "Page View"


Tag Issues

Tag Not Firing

Checklist:

  1. ✓ Trigger conditions met?
  2. ✓ Trigger enabled?
  3. ✓ Tag not paused?
  4. ✓ No blocking triggers active?
  5. ✓ Consent mode not blocking?

Debug Steps:

  1. GTM Preview > Check Tags Fired
  2. Verify trigger shows green check
  3. Check Variables tab for expected values

Duplicate Tag Firing

Symptoms: Events counted 2x in GA4 Causes:

  1. Multiple triggers on same action
  2. Page re-renders triggering again
  3. SPA virtual pageviews firing multiple times

Fix:

  1. Add "Once per event" tag firing option
  2. Use trigger groups to control firing
  3. Add conditions to prevent re-firing

Wrong Parameters Sent

Symptoms: Data appears in wrong fields in GA4 Debug:

  1. GTM Preview > Tags > Show fired tag
  2. Check "Values" sent with tag
  3. Compare with expected parameters

E-commerce Issues

Missing Transaction ID

Symptoms: Duplicate purchases counted Fix: Ensure unique transaction_id generated server-side

Items Array Empty

Symptoms: Revenue tracked but no products Check: ecommerce.items array populated

Value Mismatch

Symptoms: Revenue doesn't match actual Causes:

  1. Tax/shipping included inconsistently
  2. Currency conversion issues
  3. Discount applied incorrectly

Purchase Event Fires Multiple Times

Symptoms: Same order tracked 2-3x Causes:

  1. Page refresh on confirmation
  2. Browser back button
  3. Email link revisit

Fix:

// Check if already tracked
if (!sessionStorage.getItem('purchase_' + transaction_id)) {
  dataLayer.push({ event: 'purchase', ... });
  sessionStorage.setItem('purchase_' + transaction_id, 'true');
}

Symptoms: Tags show "Blocked by consent" in Preview Fix:

  1. Verify consent mode implementation
  2. Check default consent state
  3. Test with consent granted

Symptoms: Tags stay blocked after user accepts Fix: Verify gtag('consent', 'update', {...}) fires on accept


SPA (Single Page App) Issues

Pageviews Not Tracking Navigation

Symptoms: Only initial pageview tracked Cause: No page reload on route change

Fix: Implement History Change trigger or custom event:

// On route change
dataLayer.push({
  event: 'virtual_pageview',
  page_path: newPath,
  page_title: newTitle
});

Events Fire on Old Page Data

Symptoms: Wrong page_path in events Fix: Update page variables before event push


Content Grouping Issues (RegEx Table Variables)

How Content Grouping Works in GTM

Content grouping uses RegEx Table variables to categorize pages by URL/path patterns. The variable takes an input (typically {{Page Path}} or {{Page URL}}), tests it against an ordered list of regex patterns, and returns the first matching output value. If no pattern matches, it falls to the Default Value (usually "Other").

Key settings:

  • Full Matches Only: OFF — partial regex match is sufficient
  • Capture Groups and Replace: OFF — output is the literal value, not a regex replacement
  • Ignore Case: ON — case-insensitive matching

New Page Paths Fall Through to "Other"

Symptoms: New sections (campaigns, special events, landing pages) show as "Other" in GA4 content group reports.

Root cause: The RegEx Table was built for the site's original URL structure. New paths like /specialEvent/, /campaign/, /timesale/ don't match any existing pattern.

Example: JHR site has /specialEvent/landersshoppingfesta2026/teaser.do but only /package/ and /event/ are in the regex table, not /specialEvent/.

Fix: Add regex rule for the new path pattern. Place it BEFORE the default.

Gotcha — two variables to update: Sites often have parallel content group variables:

  1. Page Path based (e.g., (\/m)?\/specialEvent\/(.*)) — for internal reports
  2. Page URL based (e.g., full URL with domain regex) — for cross-domain or subdomain tracking

Both must be updated or they'll produce inconsistent groupings.

RegEx Pattern Conventions (JHR Example)

Page Path patterns follow this structure:

(\/m)?\/section\/(.*)    →  Korean Category Label
  • (\/m)? — optional mobile path prefix
  • \/section\/ — the URL path segment to match
  • (.*) — match anything after

Page URL patterns include domain matching:

^https\:\/\/(www|app|jpg|gjb|gjj|grp|\.)?josunhotel\.com(\/m)?\/section\/(.*)
  • Multi-subdomain support via alternation group
  • Same (\/m)? mobile prefix handling

Content Group Categories (Hospitality Reference)

Pattern Category (KR) Category (EN)
/intro.do, /main.do 메인페이지 Main Page
/about/, /press/ 기업 소개 Corporate Info
/hotel/ 호텔 소개 Hotel Info
/rooms/ 객실 소개 Room Info
/dining/ 다이닝 이용 Dining
/facilities/, /meeting/, /fitness/ 부대시설 소개 Facilities
/package/, /event/ 이벤트 | 패키지 조회 Events & Packages
/specialEvent/ 캠페인 | 프로모션 Campaign & Promotion
/timesale/, /campaign/ (placeholder — not actual paths yet, replace when specific paths are registered) 캠페인 | 프로모션 Campaign & Promotion
/activity/ 액티비티 소개 Activities
/step[0-4] 룸, 패키지 예약 프로세스 Booking Process
/resve/dining/ 다이닝 예약 프로세스 Dining Booking
/membership/ 멤버쉽 Membership
/mypage/, /login/, /join/ 웹회원 관련 Member Portal
/retail/, /product/, /office/ 리테일 관련 Retail
/voc/, /customer/ 고객지원 Customer Support
/policy/ 웹사이트 정책 Website Policy
/upload_file/event/html/ 캠페인 | 프로모션 Campaign & Promotion
Default Other Other

Two Content Group Variables — Old vs New (JHR)

The JHR container has two content group variables for menu categories:

Contents Group 2 (ID:1234) Contents Group new (ID:1826)
Input {{Page Path}} {{Page URL}}
Rules 20 24 (replacement)
Domain matching No — path only Yes — full URL with subdomain alternation
Subdomain coverage N/A www|app|jpg|gjb|gjj|grp|les|\.
Cross-domain No Yes — booking, josuntns, lounge subdomains
Mobile path (\/m)? prefix (\/m)? prefix within URL pattern

"Contents Group new" (ID:1826) is the replacement — it handles subdomains (booking, T&S, lounge, les) that the old path-based variable cannot distinguish. When auditing, check which variable is referenced in the GA4 config tag — the newer one should be used.

Gotcha — adding new subdomains: When a new hotel brand subdomain launches (e.g., les.josunhotel.com), the subdomain alternation group (www|app|...|les|\.) in ALL main-domain rules must be updated. This affects 14+ rules in the URL-based variable.

Audit Checklist for Content Grouping

  • Run dtm var info <var_id> to dump the full regex table
  • Check if new site sections have matching patterns
  • Verify both Path and URL variables are in sync
  • Check GA4 config tag references the correct variable
  • Test in GTM Preview: navigate to new page, check variable value
  • After update, verify in GA4 Realtime > Content Group report

Performance Issues

Tags Slowing Page Load

Symptoms: High LCP, slow TTI Causes:

  1. Too many synchronous tags
  2. Large third-party scripts
  3. Tags in wrong firing sequence

Fix:

  1. Use tag sequencing
  2. Load non-critical tags on Window Loaded
  3. Defer marketing tags