Files
claude-skills-reference/marketing-skill/analytics-tracking/references/gtm-patterns.md
Alireza Rezvani 52321c86bc feat: Marketing Division expansion — 7 → 42 skills (#266)
* feat: Skill Authoring Standard + Marketing Expansion plans

SKILL-AUTHORING-STANDARD.md — the DNA of every skill in this repo:
10 universal patterns codified from C-Suite innovations + Corey Haines' marketingskills patterns:

1. Context-First: check domain context, ask only for gaps
2. Practitioner Voice: expert persona, goal-oriented, not textbook
3. Multi-Mode Workflows: build from scratch / optimize existing / situation-specific
4. Related Skills Navigation: when to use, when NOT to, bidirectional
5. Reference Separation: SKILL.md lean (≤10KB), refs deep
6. Proactive Triggers: surface issues without being asked
7. Output Artifacts: request → specific deliverable mapping
8. Quality Loop: self-verify, confidence tagging
9. Communication Standard: bottom line first, structured output
10. Python Tools: stdlib-only, CLI-first, JSON output, sample data

Marketing expansion plans for 40-skill marketing division build.

* feat: marketing foundation — context + ops router + authoring standard

marketing-context/: Foundation skill every marketing skill reads first
  - SKILL.md: 3 modes (auto-draft, guided interview, update)
  - templates/marketing-context-template.md: 14 sections covering
    product, audience, personas, pain points, competitive landscape,
    differentiation, objections, switching dynamics, customer language
    (verbatim), brand voice, style guide, proof points, SEO context, goals
  - scripts/context_validator.py: Scores completeness 0-100, section-by-section

marketing-ops/: Central router for 40-skill marketing ecosystem
  - Full routing matrix: 7 pods + cross-domain routing to 6 skills in
    business-growth, product-team, engineering-team, c-level-advisor
  - Campaign orchestration sequences (launch, content, CRO sprint)
  - Quality gate matching C-Suite standard
  - scripts/campaign_tracker.py: Campaign status tracking with progress,
    overdue detection, pod coverage, blocker identification

SKILL-AUTHORING-STANDARD.md: Universal DNA for all skills
  - 10 patterns: context-first, practitioner voice, multi-mode workflows,
    related skills navigation, reference separation, proactive triggers,
    output artifacts, quality loop, communication standard, python tools
  - Quality checklist for skill completion verification
  - Domain context file mapping for all 5 domains

* feat: import 20 workspace marketing skills + standard sections

Imported 20 marketing skills from OpenClaw workspace into repo:

Content Pod (5):
  content-strategy, copywriting, copy-editing, social-content, marketing-ideas

SEO Pod (2):
  seo-audit (+ references enriched by subagent), programmatic-seo (+ refs)

CRO Pod (5):
  page-cro, form-cro, signup-flow-cro, onboarding-cro, popup-cro, paywall-upgrade-cro

Channels Pod (2):
  email-sequence, paid-ads

Growth + Intel + GTM (5):
  ab-test-setup, competitor-alternatives, marketing-psychology, launch-strategy, brand-guidelines

All 29 skills now have standard sections per SKILL-AUTHORING-STANDARD.md:
   Proactive Triggers (4-5 per skill)
   Output Artifacts table
   Communication standard reference
   Related Skills with WHEN/NOT disambiguation

Subagents enriched 8 skills with additional reference docs:
  seo-audit, programmatic-seo, page-cro, form-cro,
  onboarding-cro, popup-cro, paywall-upgrade-cro, email-sequence

43 files, 10,566 lines added.

* feat: build 13 new marketing skills + social-media-manager upgrade

All skills are 100% original work — inspired by industry best practices,
written from scratch in our own voice following SKILL-AUTHORING-STANDARD.md.

NEW Content Pod (2):
  content-production — full research→draft→optimize pipeline, content_scorer.py
  content-humanizer — AI pattern detection + voice injection, humanizer_scorer.py

NEW SEO Pod (3):
  ai-seo — AI search optimization (AEO/GEO/LLMO), entirely new category
  schema-markup — JSON-LD structured data, schema_validator.py
  site-architecture — URL structure + internal linking, sitemap_analyzer.py

NEW Channels Pod (2):
  cold-email — B2B outreach (distinct from email-sequence lifecycle)
  ad-creative — bulk ad generation + platform specs, ad_copy_validator.py

NEW Growth Pod (3):
  churn-prevention — cancel flows + save offers + dunning, churn_impact_calculator.py
  referral-program — referral + affiliate programs
  free-tool-strategy — engineering as marketing

NEW Intelligence Pod (1):
  analytics-tracking — GA4/GTM setup + event taxonomy, tracking_plan_generator.py

NEW Sales Pod (1):
  pricing-strategy — pricing, packaging, monetization

UPGRADED:
  social-media-analyzer → social-media-manager (strategy, calendar, community)

Totals: 42 skills, 27 Python scripts, 60 reference docs, 163 files, 43,265 lines

* feat: update index, marketplace, README for 42 marketing skills

- skills-index.json: 89 → 124 skills (42 marketing entries)
- marketplace.json: marketing-skills v2.0.0 (42 skills, 27 tools)
- README.md: badge 134 → 169, marketing row updated
- prompt-engineer-toolkit: added YAML frontmatter
- Removed build logs from repo
- Parity check: 42/42 passed (YAML + Related + Proactive + Output + Communication)

* fix: merge content-creator into content-production, split marketing-psychology

Quality audit fixes:

1. content-creator → DEPRECATED redirect
   - Scripts (brand_voice_analyzer.py, seo_optimizer.py) moved to content-production
   - SKILL.md replaced with redirect to content-production + content-strategy
   - Eliminates duplicate routing confusion

2. marketing-psychology → 24KB split to 6.8KB + reference
   - 70+ mental models moved to references/mental-models-catalog.md (397 lines)
   - SKILL.md now lean: categories overview, most-used models, quick reference
   - Saves ~4,300 tokens per invocation

* feat: add plugin configs, Codex/OpenClaw compatibility, ClawHub packaging

- marketing-skill/SKILL.md: ClawHub-compatible root with Quick Start for Claude Code, Codex CLI, OpenClaw
- marketing-skill/CLAUDE.md: Agent instructions (routing, context, anti-patterns)
- marketing-skill/.codex/instructions.md: Codex CLI skill routing
- .claude-plugin/marketplace.json: deduplicated, marketing-skills v2.0.0
- .codex/skills-index.json: content-creator marked deprecated, psychology updated
- Total: 42 skills, 27 Python tools, 60 references, 18 plugins

* feat: add 16 Python tools to knowledge-only skills

Enriched 12 previously tool-less skills with practical Python scripts:
- seo-audit/seo_checker.py — HTML on-page SEO analysis (0-100)
- copywriting/headline_scorer.py — headline quality scoring (0-100)
- copy-editing/readability_scorer.py — Flesch + passive + filler detection
- content-strategy/topic_cluster_mapper.py — keyword clustering
- page-cro/conversion_audit.py — HTML CRO signal analysis (0-100)
- paid-ads/roas_calculator.py — ROAS/CPA/CPL calculator
- email-sequence/sequence_analyzer.py — email sequence scoring (0-100)
- form-cro/form_field_analyzer.py — form field CRO audit (0-100)
- onboarding-cro/activation_funnel_analyzer.py — funnel drop-off analysis
- programmatic-seo/url_pattern_generator.py — URL pattern planning
- ab-test-setup/sample_size_calculator.py — statistical sample sizing
- signup-flow-cro/funnel_drop_analyzer.py — signup funnel analysis
- launch-strategy/launch_readiness_scorer.py — launch checklist scoring
- competitor-alternatives/comparison_matrix_builder.py — feature comparison
- social-media-manager/social_calendar_generator.py — content calendar
- readability_scorer.py — fixed demo mode for non-TTY execution

All 43/43 scripts pass execution. All stdlib-only, zero pip installs.
Total: 42 skills, 43 Python tools, 60+ reference docs.

* feat: add 3 more Python tools + improve 6 existing scripts

New tools from build agent:
- email-sequence/scripts/sequence_analyzer.py — email sequence scoring (91/100 demo)
- paid-ads/scripts/roas_calculator.py — ROAS/CPA/CPL/break-even calculator
- competitor-alternatives/scripts/comparison_matrix_builder.py — feature matrix

Improved scripts (better demo modes, fuller analysis):
- seo_checker.py, headline_scorer.py, readability_scorer.py,
  conversion_audit.py, topic_cluster_mapper.py, launch_readiness_scorer.py

Total: 42 skills, 47 Python tools, all passing.

* fix: remove duplicate scripts from deprecated content-creator

Scripts already live in content-production/scripts/. The content-creator
directory is now a pure redirect (SKILL.md only + legacy assets/refs).

* fix: scope VirusTotal scan to executable files only

Skip scanning .md, .py, .json, .yml — they're plain text files
that VirusTotal can't meaningfully analyze. This prevents 429 rate
limit errors on PRs with many text file changes (like 42 marketing skills).

Scan still covers: .js, .ts, .sh, .mjs, .cjs, .exe, .dll, .so, .bin, .wasm

---------

Co-authored-by: Leo <leo@openclaw.ai>
2026-03-06 03:56:16 +01:00

8.2 KiB

GTM Patterns for SaaS

Common Google Tag Manager configurations for SaaS applications.


Container Architecture

Naming Convention

Use consistent naming or GTM becomes a black box within 6 months.

Tags:     [Platform] - [Event Name]           e.g., "GA4 - signup_completed"
Triggers: [Type] - [Description]             e.g., "DL Event - signup_completed"
Variables: [Type] - [Parameter Name]         e.g., "DLV - plan_name"

Required Variables (Create These First)

Variable Name Type Value
CON - GA4 Measurement ID Constant G-XXXXXXXXXX
CON - Environment Constant production
JS - Page Path Custom JavaScript function() { return window.location.pathname; }
JS - User ID Custom JavaScript `function() { return window.currentUserId

GA4 Configuration Tag

One tag, fires on All Pages:

Tag Type: Google Analytics: GA4 Configuration
Measurement ID: {{CON - GA4 Measurement ID}}
Fields to Set:
  - user_id: {{JS - User ID}}
Trigger: All Pages

Pattern Library

Pattern 1: Data Layer Push Event

The most reliable pattern. Your app pushes structured data; GTM listens.

In your application code:

// Call this function on any trackable event
function trackEvent(eventName, parameters) {
  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({
    event: eventName,
    ...parameters
  });
}

// Example: after successful signup
trackEvent('signup_completed', {
  signup_method: 'email',
  user_id: newUser.id,
  plan_name: 'trial'
});

In GTM:

  1. Create Data Layer Variables for each parameter:

    • DLV - signup_method → Data Layer Variable → signup_method
    • DLV - user_id → Data Layer Variable → user_id
    • DLV - plan_name → Data Layer Variable → plan_name
  2. Create Trigger:

    • Type: Custom Event
    • Event Name: signup_completed
    • Name: DL Event - signup_completed
  3. Create Tag:

    • Type: Google Analytics: GA4 Event
    • Configuration Tag: GA4 Config tag
    • Event Name: signup_completed
    • Event Parameters:
      • method: {{DLV - signup_method}}
      • user_id: {{DLV - user_id}}
      • plan_name: {{DLV - plan_name}}
    • Trigger: DL Event - signup_completed

Pattern 2: Click Event on Specific Element

Use when you can't modify app code and need to track a specific CTA.

GTM Setup:

  1. Enable Click - All Elements built-in variables (if not enabled):

    • GTM → Variables → Configure → Enable: Click Element, Click ID, Click Classes, Click Text
  2. Create Trigger:

    • Type: Click - All Elements
    • Fire On: Some Clicks
    • Conditions:
      • Click Element matches CSS selector: [data-track="demo-cta"] OR
      • Click Text equals "Request a Demo"
    • Name: Click - Demo CTA
  3. Create Tag:

    • Type: GA4 Event
    • Event Name: demo_requested
    • Event Parameters:
      • page_location: {{Page URL}}
      • click_text: {{Click Text}}
    • Trigger: Click - Demo CTA

Best practice: Add data-track attributes to important elements in your HTML rather than relying on brittle CSS selectors or text matching.

<button data-track="demo-cta" data-track-source="pricing-hero">
  Request a Demo
</button>

Pattern 3: Form Submission Tracking

Two approaches depending on whether the form submits via JavaScript or full page reload.

For JavaScript-handled forms (AJAX/fetch):

  • Use Pattern 1 (dataLayer push) after successful form submission callback

For traditional form submit:

  1. Create Trigger:

    • Type: Form Submission
    • Check Validation: (only fires if form passes HTML5 validation)
    • Enable History Change: (for SPAs)
    • Fire On: Some Forms
    • Conditions: Form ID equals contact-form OR Form Classes contains js-track-form
    • Name: Form Submit - Contact
  2. Create Tag:

    • Type: GA4 Event
    • Event Name: form_submitted
    • Parameters:
      • form_name: contact
      • page_location: {{Page URL}}
    • Trigger: Form Submit - Contact

Pattern 4: SPA Page View Tracking

Single-page apps often don't trigger standard page view events on route changes.

Approach A: History Change trigger (simplest)

  1. Create Trigger:

    • Type: History Change
    • Name: History Change - Route
  2. Create Tag:

    • Type: GA4 Event
    • Event Name: page_view
    • Parameters:
      • page_location: {{Page URL}}
      • page_title: {{Page Title}}
    • Trigger: History Change - Route

Important: Disable the default pageview in your GA4 Configuration tag if using this, or you'll get duplicates on initial load.

Approach B: dataLayer push from router (more reliable)

// In your router's navigation handler:
router.afterEach((to, from) => {
  window.dataLayer.push({
    event: 'page_view',
    page_path: to.path,
    page_title: document.title
  });
});

Pattern 5: Scroll Depth Tracking

For content engagement measurement:

Option A: Use GA4 Enhanced Measurement (90% depth only)

  • Enable in GA4 → Data Streams → Enhanced Measurement → Scrolls
  • Fires when user scrolls 90% down the page
  • No GTM configuration needed

Option B: Custom milestones via GTM

  1. Create Trigger for each depth:

    • Type: Scroll Depth
    • Vertical Scroll Depths: 25, 50, 75, 100 (percent)
    • Enable for: Some Pages → Page Path contains /blog/
    • Name: Scroll Depth - Blog
  2. Create Tag:

    • Type: GA4 Event
    • Event Name: content_scrolled
    • Parameters:
      • scroll_depth_pct: {{Scroll Depth Threshold}}
      • page_location: {{Page URL}}
    • Trigger: Scroll Depth - Blog

For GDPR compliance — connect your CMP to GTM.

Basic Consent Mode (blocks all when declined):

// In your CMP callback:
window.dataLayer.push({
  event: 'cookie_consent_update',
  ad_storage: 'denied',         // or 'granted'
  analytics_storage: 'denied',  // or 'granted'
  functionality_storage: 'denied',
  personalization_storage: 'denied',
  security_storage: 'granted'   // always granted
});

Advanced Consent Mode (modeled data for declined users):

Add to <head> BEFORE GTM loads:

window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}

// Default all to denied
gtag('consent', 'default', {
  ad_storage: 'denied',
  analytics_storage: 'denied',
  wait_for_update: 500  // ms to wait for CMP to initialize
});

Then update when user consents:

gtag('consent', 'update', {
  analytics_storage: 'granted'
});

GTM Version Control

Version Naming Convention

v1.0 - Initial setup: GA4 + core events
v1.1 - Add: checkout tracking
v1.2 - Fix: duplicate pageview on SPA
v2.0 - Overhaul: new event taxonomy + Meta Pixel

Publishing Protocol

  1. Test in GTM Preview mode — verify events fire correctly
  2. Test in GA4 DebugView — confirm parameters are captured
  3. Test with GTM's "What changed?" diff view
  4. Add version notes (what changed + why)
  5. Publish to production
  6. Verify in GA4 Realtime view post-publish

Environments

Create a staging environment in GTM (Admin → Environments):

  • Development: test changes without affecting production
  • Staging: validate before publish
  • Production: live

Share staging GTM snippet with your dev team so they test against the same container.


Common GTM Mistakes

Mistake Symptom Fix
Tag fires on "All Pages" when it should be scoped Inflated event counts Add page conditions to trigger
Data Layer Variable path is wrong Parameter shows as undefined Use GTM Preview to inspect dataLayer structure
GA4 Configuration tag fires multiple times Duplicate sessions/users Check all triggers — should be one trigger, "All Pages"
Enhanced Measurement conflicts with custom tags Duplicate outbound click events Disable conflicting Enhanced Measurement settings
Trigger fires before DOM ready Element not found errors Change trigger type from "Page View" to "DOM Ready" or "Window Loaded"
Form trigger doesn't fire Form uses AJAX or custom submit Switch to dataLayer push after submit callback