gtm-implementation

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

GTM Implementation - DataLayer + GTM API

GTM 实现方案 - DataLayer + GTM API

Implement complete GTM tracking by adding dataLayer events to your code AND creating GTM variables, triggers, and tags via API.
通过在代码中添加dataLayer事件,并通过API创建GTM变量、触发器和标签,实现完整的GTM追踪。

Core Mission

核心目标

Transform analytics-ready DOM elements into fully tracked events with:
  1. Code Implementation: Add dataLayer.push() calls to React/Next.js/Vue components
  2. GTM Configuration: Create variables, triggers, and tags via GTM API
将支持分析的DOM元素转换为可完全追踪的事件,包含以下两部分:
  1. 代码实现:在React/Next.js/Vue组件中添加dataLayer.push()调用
  2. GTM配置:通过GTM API创建变量、触发器和标签

Workflow

工作流程

Phase 1: Context & Prerequisites

阶段1:上下文与前置条件

Step 1.1: Load Tracking Plan
Check for gtm-tracking-plan.json (from gtm-strategy skill):
- If exists → Load events and parameters
- If missing → Ask user which events to implement OR suggest running gtm-strategy first

Check for gtm-config.json and gtm-token.json (from gtm-setup skill):
- If missing → Suggest running gtm-setup skill first
- If exists → Verify API connection
Step 1.2: Detect Framework
Check package.json:
- React version
- Next.js version and router type (App Router vs Pages Router)
- Vue version
- TypeScript vs JavaScript

This determines:
- Component file extensions (.tsx vs .jsx vs .vue)
- Import patterns
- Syntax for className vs class
- 'use client' directive for Next.js App Router
Step 1.3: Scan for Target Elements
Using Glob and Grep, find elements to instrument:

For CTA tracking:
- Search for: class=".*js-cta.*" or id="cta_.*"
- Search for: <button, <Link components

For form tracking:
- Search for: class=".*js-form.*" or id="form_.*"
- Search for: <form tags with onSubmit handlers

For navigation tracking:
- Search for: class=".*js-nav.*" or id="nav_.*"
- Search for: <Link, <a tags

Match found elements against events in tracking plan.
步骤1.1:加载追踪计划
检查是否存在gtm-tracking-plan.json(来自gtm-strategy技能):
- 若存在 → 加载事件和参数
- 若缺失 → 询问用户需要实现哪些事件,或建议先运行gtm-strategy技能

检查是否存在gtm-config.json和gtm-token.json(来自gtm-setup技能):
- 若缺失 → 建议先运行gtm-setup技能
- 若存在 → 验证API连接
步骤1.2:检测框架
检查package.json:
- React版本
- Next.js版本及路由类型(App Router 或 Pages Router)
- Vue版本
- 使用TypeScript还是JavaScript

检测结果将决定:
- 组件文件扩展名(.tsx、.jsx 或 .vue)
- 导入模式
- className与class的语法差异
- Next.js App Router所需的'use client'指令
步骤1.3:扫描目标元素
使用Glob和Grep查找需要植入追踪的元素:

针对CTA追踪:
- 搜索:class=".*js-cta.*" 或 id="cta_.*"
- 搜索:<button、<Link组件

针对表单追踪:
- 搜索:class=".*js-form.*" 或 id="form_.*"
- 搜索:带有onSubmit处理函数的<form标签

针对导航追踪:
- 搜索:class=".*js-nav.*" 或 id="nav_.*"
- 搜索:<Link、<a标签

将找到的元素与追踪计划中的事件进行匹配。

Phase 2: DataLayer Implementation (Code Changes)

阶段2:DataLayer 代码实现

For each event in tracking plan, implement dataLayer.push() in actual code files.
Step 2.1: CTA Click Implementation
Find target (example):
jsx
// File: app/page.tsx
<button
  className="btn primary js-track js-cta js-click js-hero"
  id="cta_hero_get_started"
>
  Get Started
</button>
Implement tracking using Edit tool:
Before:
jsx
<button
  className="btn primary js-track js-cta js-click js-hero"
  id="cta_hero_get_started"
>
  Get Started
</button>
After:
jsx
<button
  className="btn primary js-track js-cta js-click js-hero"
  id="cta_hero_get_started"
  onClick={() => {
    if (typeof window !== 'undefined' && window.dataLayer) {
      window.dataLayer.push({
        event: 'cta_click',
        cta_location: 'hero',
        cta_type: 'primary',
        cta_text: 'Get Started',
        cta_destination: '/signup'
      })
    }
  }}
>
  Get Started
</button>
Framework-Specific Considerations:
Next.js App Router (requires 'use client'):
tsx
'use client'

import { useRouter } from 'next/navigation'

export default function HeroCTA() {
  const router = useRouter()

  return (
    <button
      className="btn primary js-track js-cta js-click js-hero"
      id="cta_hero_get_started"
      onClick={() => {
        // Track event
        if (typeof window !== 'undefined' && window.dataLayer) {
          window.dataLayer.push({
            event: 'cta_click',
            cta_location: 'hero',
            cta_type: 'primary',
            cta_text: 'Get Started',
            cta_destination: '/signup'
          })
        }
        // Navigate
        router.push('/signup')
      }}
    >
      Get Started
    </button>
  )
}
Step 2.2: Form Submit Implementation
Find target:
jsx
<form
  className="contact-form js-track js-form js-submit js-hero"
  id="form_hero_contact"
  onSubmit={handleSubmit}
>
Implement tracking:
Before:
jsx
<form
  className="contact-form js-track js-form js-submit js-hero"
  id="form_hero_contact"
  onSubmit={handleSubmit}
>
After:
jsx
<form
  className="contact-form js-track js-form js-submit js-hero"
  id="form_hero_contact"
  onSubmit={(e) => {
    // Track form submission
    if (typeof window !== 'undefined' && window.dataLayer) {
      window.dataLayer.push({
        event: 'form_submit',
        form_name: 'contact',
        form_location: 'hero',
        form_type: 'contact_request'
      })
    }
    // Call original handler
    handleSubmit(e)
  }}
>
Step 2.3: Navigation Click Implementation
Find target (Next.js Link):
jsx
<Link href="/pricing">Pricing</Link>
Implement tracking:
Before:
jsx
<Link
  href="/pricing"
  className="nav-link js-track js-nav js-click js-header"
  id="nav_header_pricing"
>
  Pricing
</Link>
After:
jsx
<Link
  href="/pricing"
  className="nav-link js-track js-nav js-click js-header"
  id="nav_header_pricing"
  onClick={() => {
    if (typeof window !== 'undefined' && window.dataLayer) {
      window.dataLayer.push({
        event: 'navigation_click',
        nav_location: 'header',
        nav_type: 'menu_link',
        nav_text: 'Pricing',
        nav_destination: '/pricing'
      })
    }
  }}
>
  Pricing
</Link>
Step 2.4: Parameter Extraction Logic
Extract parameters from DOM elements intelligently:
cta_location: From ID attribute
javascript
// id="cta_hero_get_started" → location: "hero"
const id = element.getAttribute('id') // "cta_hero_get_started"
const location = id.split('_')[1] // "hero"
cta_text: From button innerText
jsx
// <button>Get Started</button> → cta_text: "Get Started"
cta_text: 'Get Started'
cta_destination: From href or programmatic navigation
javascript
// <Link href="/signup"> → cta_destination: "/signup"
// onClick={() => router.push('/pricing')} → cta_destination: "/pricing"
cta_type: From CSS classes
javascript
// className includes "btn-primary" → type: "primary"
// className includes "btn-secondary" → type: "secondary"
针对追踪计划中的每个事件,在实际代码文件中实现dataLayer.push()。
步骤2.1:CTA点击事件实现
查找目标元素(示例):
jsx
// 文件:app/page.tsx
<button
  className="btn primary js-track js-cta js-click js-hero"
  id="cta_hero_get_started"
>
  Get Started
</button>
使用编辑工具实现追踪
实现前
jsx
<button
  className="btn primary js-track js-cta js-click js-hero"
  id="cta_hero_get_started"
>
  Get Started
</button>
实现后
jsx
<button
  className="btn primary js-track js-cta js-click js-hero"
  id="cta_hero_get_started"
  onClick={() => {
    if (typeof window !== 'undefined' && window.dataLayer) {
      window.dataLayer.push({
        event: 'cta_click',
        cta_location: 'hero',
        cta_type: 'primary',
        cta_text: 'Get Started',
        cta_destination: '/signup'
      })
    }
  }}
>
  Get Started
</button>
框架特定注意事项
Next.js App Router(需要'use client'指令):
tsx
'use client'

import { useRouter } from 'next/navigation'

export default function HeroCTA() {
  const router = useRouter()

  return (
    <button
      className="btn primary js-track js-cta js-click js-hero"
      id="cta_hero_get_started"
      onClick={() => {
        // 追踪事件
        if (typeof window !== 'undefined' && window.dataLayer) {
          window.dataLayer.push({
            event: 'cta_click',
            cta_location: 'hero',
            cta_type: 'primary',
            cta_text: 'Get Started',
            cta_destination: '/signup'
          })
        }
        // 跳转页面
        router.push('/signup')
      }}
    >
      Get Started
    </button>
  )
}
步骤2.2:表单提交事件实现
查找目标元素
jsx
<form
  className="contact-form js-track js-form js-submit js-hero"
  id="form_hero_contact"
  onSubmit={handleSubmit}
>
实现追踪
实现前
jsx
<form
  className="contact-form js-track js-form js-submit js-hero"
  id="form_hero_contact"
  onSubmit={handleSubmit}
>
实现后
jsx
<form
  className="contact-form js-track js-form js-submit js-hero"
  id="form_hero_contact"
  onSubmit={(e) => {
    // 追踪表单提交
    if (typeof window !== 'undefined' && window.dataLayer) {
      window.dataLayer.push({
        event: 'form_submit',
        form_name: 'contact',
        form_location: 'hero',
        form_type: 'contact_request'
      })
    }
    // 调用原处理函数
    handleSubmit(e)
  }}
>
步骤2.3:导航点击事件实现
查找目标元素(Next.js Link):
jsx
<Link href="/pricing">Pricing</Link>
实现追踪
实现前
jsx
<Link
  href="/pricing"
  className="nav-link js-track js-nav js-click js-header"
  id="nav_header_pricing"
>
  Pricing
</Link>
实现后
jsx
<Link
  href="/pricing"
  className="nav-link js-track js-nav js-click js-header"
  id="nav_header_pricing"
  onClick={() => {
    if (typeof window !== 'undefined' && window.dataLayer) {
      window.dataLayer.push({
        event: 'navigation_click',
        nav_location: 'header',
        nav_type: 'menu_link',
        nav_text: 'Pricing',
        nav_destination: '/pricing'
      })
    }
  }}
>
  Pricing
</Link>
步骤2.4:参数提取逻辑
智能地从DOM元素中提取参数:
cta_location:从ID属性提取
javascript
// id="cta_hero_get_started" → location: "hero"
const id = element.getAttribute('id') // "cta_hero_get_started"
const location = id.split('_')[1] // "hero"
cta_text:从按钮的innerText提取
jsx
// <button>Get Started</button> → cta_text: "Get Started"
cta_text: 'Get Started'
cta_destination:从href或程序化导航逻辑提取
javascript
// <Link href="/signup"> → cta_destination: "/signup"
// onClick={() => router.push('/pricing')} → cta_destination: "/pricing"
cta_type:从CSS类名提取
javascript
// className包含"btn-primary" → type: "primary"
// className包含"btn-secondary" → type: "secondary"

Phase 3: GTM Container Configuration (API Calls)

阶段3:GTM容器配置(API调用)

Create variables, triggers, and tags via GTM API to process the dataLayer events.
Step 3.1: Create Data Layer Variables
For each parameter in each event, create a GTM variable:
Example: cta_click event needs 4 variables
javascript
// Variable 1: CTA Location
{
  name: "DLV - CTA Location",
  type: "v",
  parameter: [
    { type: "TEMPLATE", key: "name", value: "cta_location" },
    { type: "INTEGER", key: "dataLayerVersion", value: "2" }
  ]
}

// Variable 2: CTA Type
{
  name: "DLV - CTA Type",
  type: "v",
  parameter: [
    { type: "TEMPLATE", key: "name", value: "cta_type" },
    { type: "INTEGER", key: "dataLayerVersion", value: "2" }
  ]
}

// Variable 3: CTA Text
{
  name: "DLV - CTA Text",
  type: "v",
  parameter: [
    { type: "TEMPLATE", key: "name", value: "cta_text" },
    { type: "INTEGER", key: "dataLayerVersion", value: "2" }
  ]
}

// Variable 4: CTA Destination
{
  name: "DLV - CTA Destination",
  type: "v",
  parameter: [
    { type: "TEMPLATE", key: "name", value: "cta_destination" },
    { type: "INTEGER", key: "dataLayerVersion", value: "2" }
  ]
}
Use GTM API to create:
javascript
tagmanager.accounts.containers.workspaces.variables.create({
  parent: `accounts/${accountId}/containers/${containerId}/workspaces/${workspaceId}`,
  requestBody: variableConfig
})
Step 3.2: Create Custom Event Triggers
For each event, create a trigger that fires on that custom event:
Example: cta_click trigger
javascript
{
  name: "CE - CTA Click",
  type: "CUSTOM_EVENT",
  customEventFilter: [
    {
      type: "EQUALS",
      parameter: [
        { type: "TEMPLATE", key: "arg0", value: "{{_event}}" },
        { type: "TEMPLATE", key: "arg1", value: "cta_click" }
      ]
    }
  ]
}
Use GTM API to create:
javascript
tagmanager.accounts.containers.workspaces.triggers.create({
  parent: `accounts/${accountId}/containers/${containerId}/workspaces/${workspaceId}`,
  requestBody: triggerConfig
})
Step 3.3: Create GA4 Event Tags
For each event, create a GA4 event tag that fires on the trigger:
Example: CTA Click tag
javascript
{
  name: "GA4 - CTA Click",
  type: "gaawe", // GA4 Event tag type
  parameter: [
    {
      type: "TEMPLATE",
      key: "eventName",
      value: "cta_click"
    },
    {
      type: "LIST",
      key: "eventParameters",
      list: [
        {
          type: "MAP",
          map: [
            { type: "TEMPLATE", key: "name", value: "cta_location" },
            { type: "TEMPLATE", key: "value", value: "{{DLV - CTA Location}}" }
          ]
        },
        {
          type: "MAP",
          map: [
            { type: "TEMPLATE", key: "name", value: "cta_type" },
            { type: "TEMPLATE", key: "value", value: "{{DLV - CTA Type}}" }
          ]
        },
        {
          type: "MAP",
          map: [
            { type: "TEMPLATE", key: "name", value: "cta_text" },
            { type: "TEMPLATE", key: "value", value: "{{DLV - CTA Text}}" }
          ]
        },
        {
          type: "MAP",
          map: [
            { type: "TEMPLATE", key: "name", value: "cta_destination" },
            { type: "TEMPLATE", key: "value", value: "{{DLV - CTA Destination}}" }
          ]
        }
      ]
    },
    {
      type: "TAG_REFERENCE",
      key: "measurementId",
      value: "{{GA4 Configuration Tag}}" // Reference to GA4 config tag
    }
  ],
  firingTriggerId: ["{{CE - CTA Click trigger ID}}"]
}
Use GTM API to create:
javascript
tagmanager.accounts.containers.workspaces.tags.create({
  parent: `accounts/${accountId}/containers/${containerId}/workspaces/${workspaceId}`,
  requestBody: tagConfig
})
Step 3.4: Handle Incremental Updates
Check for existing variables/triggers/tags before creating:
javascript
// List existing variables
const existingVariables = await tagmanager.accounts.containers.workspaces.variables.list({
  parent: `accounts/${accountId}/containers/${containerId}/workspaces/${workspaceId}`
})

// Check if "DLV - CTA Location" already exists
const exists = existingVariables.data.variable?.find(v => v.name === "DLV - CTA Location")

if (exists) {
  // Update existing variable
  tagmanager.accounts.containers.workspaces.variables.update({
    path: exists.path,
    requestBody: variableConfig
  })
} else {
  // Create new variable
  tagmanager.accounts.containers.workspaces.variables.create({...})
}
通过GTM API创建变量、触发器和标签,以处理dataLayer事件。
步骤3.1:创建数据层变量
针对每个事件中的每个参数,创建一个GTM变量:
示例:cta_click事件需要4个变量
javascript
// 变量1:CTA Location
{
  name: "DLV - CTA Location",
  type: "v",
  parameter: [
    { type: "TEMPLATE", key: "name", value: "cta_location" },
    { type: "INTEGER", key: "dataLayerVersion", value: "2" }
  ]
}

// 变量2:CTA Type
{
  name: "DLV - CTA Type",
  type: "v",
  parameter: [
    { type: "TEMPLATE", key: "name", value: "cta_type" },
    { type: "INTEGER", key: "dataLayerVersion", value: "2" }
  ]
}

// 变量3:CTA Text
{
  name: "DLV - CTA Text",
  type: "v",
  parameter: [
    { type: "TEMPLATE", key: "name", value: "cta_text" },
    { type: "INTEGER", key: "dataLayerVersion", value: "2" }
  ]
}

// 变量4:CTA Destination
{
  name: "DLV - CTA Destination",
  type: "v",
  parameter: [
    { type: "TEMPLATE", key: "name", value: "cta_destination" },
    { type: "INTEGER", key: "dataLayerVersion", value: "2" }
  ]
}
使用GTM API创建:
javascript
tagmanager.accounts.containers.workspaces.variables.create({
  parent: `accounts/${accountId}/containers/${containerId}/workspaces/${workspaceId}`,
  requestBody: variableConfig
})
步骤3.2:创建自定义事件触发器
针对每个事件,创建一个在该自定义事件触发时生效的触发器:
示例:cta_click触发器
javascript
{
  name: "CE - CTA Click",
  type: "CUSTOM_EVENT",
  customEventFilter: [
    {
      type: "EQUALS",
      parameter: [
        { type: "TEMPLATE", key: "arg0", value: "{{_event}}" },
        { type: "TEMPLATE", key: "arg1", value: "cta_click" }
      ]
    }
  ]
}
使用GTM API创建:
javascript
tagmanager.accounts.containers.workspaces.triggers.create({
  parent: `accounts/${accountId}/containers/${containerId}/workspaces/${workspaceId}`,
  requestBody: triggerConfig
})
步骤3.3:创建GA4事件标签
针对每个事件,创建一个在触发器触发时生效的GA4事件标签:
示例:CTA Click标签
javascript
{
  name: "GA4 - CTA Click",
  type: "gaawe", // GA4 Event标签类型
  parameter: [
    {
      type: "TEMPLATE",
      key: "eventName",
      value: "cta_click"
    },
    {
      type: "LIST",
      key: "eventParameters",
      list: [
        {
          type: "MAP",
          map: [
            { type: "TEMPLATE", key: "name", value: "cta_location" },
            { type: "TEMPLATE", key: "value", value: "{{DLV - CTA Location}}" }
          ]
        },
        {
          type: "MAP",
          map: [
            { type: "TEMPLATE", key: "name", value: "cta_type" },
            { type: "TEMPLATE", key: "value", value: "{{DLV - CTA Type}}" }
          ]
        },
        {
          type: "MAP",
          map: [
            { type: "TEMPLATE", key: "name", value: "cta_text" },
            { type: "TEMPLATE", key: "value", value: "{{DLV - CTA Text}}" }
          ]
        },
        {
          type: "MAP",
          map: [
            { type: "TEMPLATE", key: "name", value: "cta_destination" },
            { type: "TEMPLATE", key: "value", value: "{{DLV - CTA Destination}}" }
          ]
        }
      ]
    },
    {
      type: "TAG_REFERENCE",
      key: "measurementId",
      value: "{{GA4 Configuration Tag}}" // 引用GA4配置标签
    }
  ],
  firingTriggerId: ["{{CE - CTA Click trigger ID}}"]
}
使用GTM API创建:
javascript
tagmanager.accounts.containers.workspaces.tags.create({
  parent: `accounts/${accountId}/containers/${containerId}/workspaces/${workspaceId}`,
  requestBody: tagConfig
})
步骤3.4:处理增量更新
在创建前检查是否已存在变量/触发器/标签:
javascript
// 列出已有的变量
const existingVariables = await tagmanager.accounts.containers.workspaces.variables.list({
  parent: `accounts/${accountId}/containers/${containerId}/workspaces/${workspaceId}`
})

// 检查"DLV - CTA Location"是否已存在
const exists = existingVariables.data.variable?.find(v => v.name === "DLV - CTA Location")

if (exists) {
  // 更新已有的变量
  tagmanager.accounts.containers.workspaces.variables.update({
    path: exists.path,
    requestBody: variableConfig
  })
} else {
  // 创建新变量
  tagmanager.accounts.containers.workspaces.variables.create({...})
}

Phase 4: Container Version Creation

阶段4:创建容器版本

After all variables/triggers/tags are created, create a new container version:
javascript
const version = await tagmanager.accounts.containers.workspaces.create_version({
  path: `accounts/${accountId}/containers/${containerId}/workspaces/${workspaceId}`,
  requestBody: {
    name: `GTM Automation - ${new Date().toISOString()}`,
    notes: `Automated implementation via gtm-implementation skill

Events implemented:
- cta_click (12 elements)
- form_submit (3 elements)
- navigation_click (8 elements)

Variables created: 12
Triggers created: 3
Tags created: 3`
  }
})

console.log(`✓ Container version created: ${version.data.containerVersionId}`)
console.log(`→ Preview in GTM: ${version.data.containerVersion.tagManagerUrl}`)
在所有变量/触发器/标签创建完成后,创建新的容器版本:
javascript
const version = await tagmanager.accounts.containers.workspaces.create_version({
  path: `accounts/${accountId}/containers/${containerId}/workspaces/${workspaceId}`,
  requestBody: {
    name: `GTM 自动化 - ${new Date().toISOString()}`,
    notes: `通过gtm-implementation技能自动实现

已实现的事件:
- cta_click(12个元素)
- form_submit(3个元素)
- navigation_click(8个元素)

已创建变量:12个
已创建触发器:3个
已创建标签:3个`
  }
})

console.log(`✓ 容器版本已创建:${version.data.containerVersionId}`)
console.log(`→ 在GTM中预览:${version.data.containerVersion.tagManagerUrl}`)

Phase 5: Summary Report

阶段5:生成总结报告

Generate comprehensive implementation summary:
=== GTM Implementation Complete ===

--- Code Changes ---
Files modified: 8

app/page.tsx:
  ✓ Added CTA click tracking (3 buttons)
  ✓ Added form submit tracking (1 form)

components/Navbar.tsx:
  ✓ Added navigation click tracking (5 links)

components/Footer.tsx:
  ✓ Added navigation click tracking (3 links)
  ✓ Added form submit tracking (1 newsletter form)

... (4 more files)

--- DataLayer Events Implemented ---
✓ cta_click (12 elements tracked)
✓ form_submit (3 elements tracked)
✓ navigation_click (8 elements tracked)

Total events: 23

--- GTM Container Configuration ---
Account: 1234567890
Container: GTM-ABC1234
Workspace: Default Workspace

Created via API:
  ✓ 12 Data Layer Variables
  ✓ 3 Custom Event Triggers
  ✓ 3 GA4 Event Tags

Container version created: 42
Preview URL: https://tagmanager.google.com/#/versions/accounts/123/containers/456/versions/42

--- Next Steps ---
1. Test tracking in GTM Preview mode
   → Invoke gtm-testing skill for guided testing

2. Review container version in GTM:
   → Open GTM → Versions → Version 42
   → Check variables, triggers, tags

3. Publish when ready:
   → GTM → Submit → Publish

Ready to test tracking? Invoke gtm-testing skill.
生成详细的实现总结:
=== GTM 实现完成 ===

--- 代码变更 ---
已修改文件:8个

app/page.tsx:
  ✓ 添加了CTA点击追踪(3个按钮)
  ✓ 添加了表单提交追踪(1个表单)

components/Navbar.tsx:
  ✓ 添加了导航点击追踪(5个链接)

components/Footer.tsx:
  ✓ 添加了导航点击追踪(3个链接)
  ✓ 添加了表单提交追踪(1个订阅表单)

...(另外4个文件)

--- 已实现的DataLayer事件 ---
✓ cta_click(已追踪12个元素)
✓ form_submit(已追踪3个元素)
✓ navigation_click(已追踪8个元素)

总事件数:23个

--- GTM容器配置 ---
账户:1234567890
容器:GTM-ABC1234
工作区:默认工作区

通过API创建的内容:
  ✓ 12个数据层变量
  ✓ 3个自定义事件触发器
  ✓ 3个GA4事件标签

已创建容器版本:42
预览URL:https://tagmanager.google.com/#/versions/accounts/123/containers/456/versions/42

--- 后续步骤 ---
1. 在GTM预览模式中测试追踪
   → 调用gtm-testing技能进行引导式测试

2. 在GTM中查看容器版本:
   → 打开GTM → 版本 → 版本42
   → 检查变量、触发器、标签

3. 准备就绪后发布:
   → GTM → 提交 → 发布

准备测试追踪了吗?调用gtm-testing技能即可。

Important Guidelines

重要指南

Code Implementation Best Practices

代码实现最佳实践

1. Preserve Existing Functionality
  • NEVER remove existing onClick handlers
  • Call original handlers AFTER tracking
  • Use wrapper functions when needed
2. Type Safety (TypeScript)
tsx
// Add proper typing
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
  // Track
  window.dataLayer?.push({...})
  // Original handler
  originalHandler(e)
}}
3. Framework-Specific Patterns
Next.js App Router:
  • Add 'use client' directive to files with onClick
  • Use useRouter from 'next/navigation'
React:
  • Use functional components with hooks
  • Maintain existing state management
Vue:
  • Use @click syntax
  • Maintain reactivity
4. Avoid Redundant Tracking
  • If element already has dataLayer.push, UPDATE it (don't duplicate)
  • Check for existing tracking code before adding new
1. 保留现有功能
  • 切勿删除现有的onClick处理函数
  • 在追踪代码之后调用原处理函数
  • 必要时使用包装函数
2. 类型安全(TypeScript)
tsx
// 添加正确的类型定义
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
  // 追踪事件
  window.dataLayer?.push({...})
  // 调用原处理函数
  originalHandler(e)
}}
3. 框架特定模式
Next.js App Router
  • 在包含onClick的文件中添加'use client'指令
  • 从'next/navigation'导入useRouter
React
  • 使用带hooks的函数式组件
  • 保留现有的状态管理逻辑
Vue
  • 使用@click语法
  • 保留响应式特性
4. 避免重复追踪
  • 如果元素已包含dataLayer.push,更新它(不要重复添加)
  • 添加新追踪代码前检查是否已有相关实现

GTM API Best Practices

GTM API最佳实践

1. Naming Conventions
  • Variables: "DLV - {Parameter Name}" (DLV = Data Layer Variable)
  • Triggers: "CE - {Event Name}" (CE = Custom Event)
  • Tags: "GA4 - {Event Name}"
2. Error Handling
javascript
try {
  await tagmanager.accounts.containers.workspaces.variables.create({...})
} catch (error) {
  if (error.code === 409) {
    // Variable already exists - update instead
  } else if (error.code === 403) {
    // Permission denied
  } else {
    throw error
  }
}
3. Batch Operations
  • Create all variables first
  • Then create triggers (which may reference variables)
  • Finally create tags (which reference both)
1. 命名规范
  • 变量:"DLV - {参数名称}"(DLV = 数据层变量)
  • 触发器:"CE - {事件名称}"(CE = 自定义事件)
  • 标签:"GA4 - {事件名称}"
2. 错误处理
javascript
try {
  await tagmanager.accounts.containers.workspaces.variables.create({...})
} catch (error) {
  if (error.code === 409) {
    // 变量已存在 - 执行更新操作
  } else if (error.code === 403) {
    // 权限不足
  } else {
    throw error
  }
}
3. 批量操作
  • 先创建所有变量
  • 再创建触发器(可能会引用变量)
  • 最后创建标签(会同时引用变量和触发器)

Parameter Extraction Intelligence

参数提取智能规则

Be smart about extracting parameters:
From ID attributes:
javascript
// id="cta_hero_get_started"
const [category, location, ...action] = id.split('_')
// category: "cta", location: "hero", action: ["get", "started"]
From class names:
javascript
// className="btn btn-primary"
const isPrimary = className.includes('primary')
const type = isPrimary ? 'primary' : 'secondary'
From content:
jsx
// <button>Get Started</button>
const text = element.innerText // "Get Started"
From href/destination:
jsx
// <Link href="/pricing">
const destination = href // "/pricing"

// onClick={() => router.push('/signup')}
// Parse from handler → destination: "/signup"
智能提取参数的方法:
从ID属性提取
javascript
// id="cta_hero_get_started"
const [category, location, ...action] = id.split('_')
// category: "cta", location: "hero", action: ["get", "started"]
从类名提取
javascript
// className="btn btn-primary"
const isPrimary = className.includes('primary')
const type = isPrimary ? 'primary' : 'secondary'
从内容提取
jsx
// <button>Get Started</button>
const text = element.innerText // "Get Started"
从href/目标地址提取
jsx
// <Link href="/pricing">
const destination = href // "/pricing"

// onClick={() => router.push('/signup')}
// 从处理函数中解析 → destination: "/signup"

Scripts

脚本文件

scripts/gtm-api-client.js

scripts/gtm-api-client.js

Core GTM API wrapper for creating variables/triggers/tags (extracted from gtm-setup-auto.js logic)
核心GTM API封装,用于创建变量/触发器/标签(从gtm-setup-auto.js逻辑中提取)

scripts/create-variables.js

scripts/create-variables.js

Variable creation logic with duplicate detection
带有重复检测的变量创建逻辑

scripts/create-triggers.js

scripts/create-triggers.js

Trigger creation logic for custom events
自定义事件的触发器创建逻辑

scripts/create-tags.js

scripts/create-tags.js

GA4 event tag creation with parameter mapping
带有参数映射的GA4事件标签创建逻辑

scripts/implement-datalayer.js

scripts/implement-datalayer.js

Analyzes tracking plan and implements dataLayer.push() in code using Edit tool
分析追踪计划,并使用编辑工具在代码中实现dataLayer.push()

References

参考文档

references/datalayer-patterns.md

references/datalayer-patterns.md

Framework-specific dataLayer implementation patterns:
  • Next.js App Router ('use client' directive)
  • Next.js Pages Router
  • React (hooks, class components)
  • Vue (composition API, options API)
  • Vanilla JavaScript
针对特定框架的DataLayer实现模式:
  • Next.js App Router('use client'指令)
  • Next.js Pages Router
  • React(hooks、类组件)
  • Vue(组合式API、选项式API)
  • 原生JavaScript

references/gtm-ui-guide.md

references/gtm-ui-guide.md

Manual GTM UI instructions as fallback if API fails
若API调用失败,可作为备选的手动GTM UI操作指南

references/event-taxonomies.md

references/event-taxonomies.md

Common event naming patterns (object_action vs action_object)
通用事件命名模式(object_action 与 action_object)

Assets

资源模板

assets/templates/saas.json

assets/templates/saas.json

Pre-built GTM config for SaaS product tracking:
  • trial_start, feature_usage, upgrade_click
  • account_created, plan_selected
针对SaaS产品追踪的预构建GTM配置:
  • trial_start、feature_usage、upgrade_click
  • account_created、plan_selected

assets/templates/ecommerce.json

assets/templates/ecommerce.json

Pre-built GTM config for e-commerce tracking:
  • product_view, add_to_cart, checkout_start
  • purchase_complete, product_search
针对电商追踪的预构建GTM配置:
  • product_view、add_to_cart、checkout_start
  • purchase_complete、product_search

Supporting Files

支持文件

  • template.md
    - Framework-specific dataLayer push code patterns and GTM API payload templates
  • examples/sample.md
    - Example implementation output showing before/after code changes and console output
  • template.md
    - 针对特定框架的DataLayer推送代码模式,以及GTM API请求体模板
  • examples/sample.md
    - 示例实现输出,展示代码变更前后的对比及控制台输出

assets/templates/lead-generation.json

assets/templates/lead-generation.json

Pre-built GTM config for lead-gen tracking:
  • form_start, form_submit, content_download
  • demo_request, newsletter_signup
针对线索生成追踪的预构建GTM配置:
  • form_start、form_submit、content_download
  • demo_request、newsletter_signup

Execution Checklist

执行检查清单

  • Tracking plan loaded or events specified
  • GTM API credentials validated
  • Framework detected
  • Target elements identified
  • DataLayer events implemented in code
  • Variables created via GTM API
  • Triggers created via GTM API
  • Tags created via GTM API
  • Container version created
  • Implementation summary generated
  • Testing instructions provided
  • 已加载追踪计划或指定了事件
  • 已验证GTM API凭证
  • 已检测框架类型
  • 已识别目标元素
  • 已在代码中实现DataLayer事件
  • 已通过GTM API创建变量
  • 已通过GTM API创建触发器
  • 已通过GTM API创建标签
  • 已创建容器版本
  • 已生成实现总结
  • 已提供测试说明

Common Questions

常见问题

Q: What if I don't have a tracking plan? A: Run gtm-strategy skill first to create one, OR specify events manually and we'll implement them.
Q: Can I implement tracking without using the GTM API? A: Yes. We'll implement dataLayer events in code and provide manual GTM UI instructions.
Q: Will this overwrite existing GTM configuration? A: No. We check for existing variables/triggers/tags and update them. New configs are added, not replaced.
Q: Can I implement tracking for only specific events? A: Yes. Specify which events to implement (e.g., "only implement cta_click tracking").
Q: What if my framework isn't supported? A: The dataLayer.push pattern works in any JavaScript environment. We'll provide vanilla JS implementation.
Q:如果我没有追踪计划怎么办? A:先运行gtm-strategy技能创建一个,或者手动指定需要实现的事件,我们会完成相应的追踪实现。
Q:我可以不使用GTM API来实现追踪吗? A:可以。我们会在代码中实现dataLayer事件,并提供手动操作GTM UI的说明。
Q:这会覆盖现有的GTM配置吗? A:不会。我们会检查已存在的变量/触发器/标签并进行更新,只会添加新的配置,不会替换原有内容。
Q:我可以只针对特定事件实现追踪吗? A:可以。指定需要实现的事件即可(例如:"仅实现cta_click追踪")。
Q:如果我的框架不被支持怎么办? A:dataLayer.push模式适用于任何JavaScript环境,我们会提供原生JS的实现方案。