mcpField
G
gtm-implementation

gtm-implementation

github.com/aimonk2025营销与增长9157 次安装35 周前更新
代码仓库

关于 gtm-implementation

gtm-implementation 是用于在 React、Next.js、Vue 等 JavaScript 代码中添加分析事件,并通过 GTM API 配置对应变量、触发器和 GA4 事件代码的技能。它涵盖从跟踪计划到创建容器版本和生成报告的实施流程。

主要功能

  1. 01在应用代码中添加 dataLayer 事件
  2. 02通过 API 配置 GTM 变量、触发器和代码
  3. 03识别框架并为目标元素添加跟踪
  4. 04更新时避免重复创建配置
  5. 05创建容器版本并生成实施报告

适用场景

  1. 01跟踪 CTA 点击、表单提交和导航
  2. 02根据现有跟踪计划实施事件
  3. 03配置 SaaS 或电商事件的 GTM 设置

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/aimonk2025/google-tag-manager-automation --skill gtm-implementation

安装后在 Claude Code 中输入/gtm-implementation确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

template.md
assets/templates/
saas.json
examples/
sample.md
references/
datalayer-patterns.md
event-taxonomies.md

详细介绍

GTM 实施 - DataLayer + GTM API

通过在代码中添加 dataLayer 事件,并通过 API 创建 GTM 变量、触发器和代码,实现完整的 GTM 跟踪。

核心任务

将适用于分析的 DOM 元素转换为完整跟踪的事件:

  1. 代码实施:在 React/Next.js/Vue 组件中添加 dataLayer.push() 调用
  2. GTM 配置:通过 GTM API 创建变量、触发器和代码

工作流

阶段 0:加载业务上下文(如果可用)

检查项目根目录中是否存在 gtm-context.md:

  • 如果存在:静默读取,并在本次技能运行过程中使用其中的业务上下文
  • 如果不存在:正常继续——在工作流过程中按常规询问上下文问题

此文件会在 gtm-analytics-audit 首次运行结束时自动创建。

阶段 1:上下文与先决条件

步骤 1.1:加载跟踪计划

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

步骤 1.2:检测框架

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

步骤 1.3:扫描目标元素

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.4:解析当前工作区(动态)

进行任何 GTM API 操作之前,始终动态解析当前工作区:

// List all workspaces for this container
const workspacesResponse = await tagmanager.accounts.containers.workspaces.list({
  parent: `accounts/${accountId}/containers/${containerId}`
})

const workspaces = workspacesResponse.data.workspace || []

if (workspaces.length === 0) {
  throw new Error('No workspaces found in this GTM container. Create one in the GTM UI first.')
}

// Always use the first available workspace
const workspace = workspaces[0]
const workspaceId = workspace.workspaceId

console.log(`✓ Active workspace: "${workspace.name}" (ID: ${workspaceId})`)

原因:在 GTM 界面中手动提交后,GTM 会删除一个工作区,并创建一个 ID 全新的工作区。gtm-config.json 中存储的 workspaceId 会因此过时。切勿假定某个特定工作区 ID 仍然存在。

阶段 2:DataLayer 实施(代码更改)

对于跟踪计划中的每个事件,都要在实际代码文件中实现 dataLayer.push()。

步骤 2.1:实现 CTA 点击跟踪

查找目标(示例):

// File: app/page.tsx
<button
  className="btn primary js-track js-cta js-click js-hero"
  id="cta_hero_get_started"
>
  Get Started
</button>

使用 Edit 工具实现跟踪:

之前:

<button
  className="btn primary js-track js-cta js-click js-hero"
  id="cta_hero_get_started"
>
  Get Started
</button>

之后:

<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'):

'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>
  )
}

步骤 2.2:实现表单提交跟踪

查找目标:

<form
  className="contact-form js-track js-form js-submit js-hero"
  id="form_hero_contact"
  onSubmit={handleSubmit}
>

实现跟踪:

之前:

<form
  className="contact-form js-track js-form js-submit js-hero"
  id="form_hero_contact"
  onSubmit={handleSubmit}
>

之后:

<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)
  }}
>

步骤 2.3:实现导航点击跟踪

查找目标(Next.js Link):

<Link href="/pricing">Pricing</Link>

实现跟踪:

之前:

<Link
  href="/pricing"
  className="nav-link js-track js-nav js-click js-header"
  id="nav_header_pricing"
>
  Pricing
</Link>

之后:

<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 属性提取

// 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 提取

// <button>Get Started</button> → cta_text: "Get Started"
cta_text: 'Get Started'

cta_destination:从 href 或程序化导航中提取

// <Link href="/signup"> → cta_destination: "/signup"
// onClick={() => router.push('/pricing')} → cta_destination: "/pricing"

cta_type:从 CSS 类中提取

// className includes "btn-primary" → type: "primary"
// className includes "btn-secondary" → type: "secondary"
阶段 3:GTM 容器配置(API 调用)

通过 GTM API 创建变量、触发器和代码,以处理 dataLayer 事件。

步骤 3.1:创建数据层变量

为每个事件中的每个参数创建一个 GTM 变量:

示例:cta_click 事件需要 4 个变量

// 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" }
  ]
}

使用 GTM API 创建:

tagmanager.accounts.containers.workspaces.variables.create({
  parent: `accounts/${accountId}/containers/${containerId}/workspaces/${workspaceId}`,
  requestBody: variableConfig
})

步骤 3.2:创建自定义事件触发器

为每个事件创建一个在该自定义事件发生时触发的触发器:

示例:cta_click 触发器

{
  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 创建:

tagmanager.accounts.containers.workspaces.triggers.create({
  parent: `accounts/${accountId}/containers/${containerId}/workspaces/${workspaceId}`,
  requestBody: triggerConfig
})

步骤 3.3:创建 GA4 事件代码

为每个事件创建一个由相应触发器触发的 GA4 事件代码:

示例:CTA 点击代码

{
  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}}"]
}

使用 GTM API 创建:

tagmanager.accounts.containers.workspaces.tags.create({
  parent: `accounts/${accountId}/containers/${containerId}/workspaces/${workspaceId}`,
  requestBody: tagConfig
})

步骤 3.4:处理增量更新

创建前检查是否已存在相应变量、触发器和代码:

// 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({...})
}
阶段 4:创建容器版本

创建所有变量、触发器和代码后,创建新的容器版本:

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}`)
阶段 5:摘要报告

生成全面的实施摘要:

=== 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: [dynamically resolved name] (ID: [resolved ID])

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.

重要指南

代码实现最佳实践

1. 保留现有功能

  • 绝不要移除现有的 onClick 处理程序
  • 跟踪后再调用原有处理程序
  • 必要时使用包装函数

2. 类型安全(TypeScript)

// Add proper typing
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
  // Track
  window.dataLayer?.push({...})
  // Original handler
  originalHandler(e)
}}

3. 特定框架的模式

Next.js App Router:

  • 为包含 onClick 的文件添加 'use client' 指令
  • 使用 'next/navigation' 中的 useRouter

React:

  • 使用带钩子的函数组件
  • 保持现有状态管理方式

Vue:

  • 使用 @click 语法
  • 保持响应性

4. 避免冗余跟踪

  • 如果元素已有 dataLayer.push,请更新它(不要重复添加)
  • 添加新代码前,先检查是否已有跟踪代码
GTM API 最佳实践

1. 命名约定

  • 变量:"DLV - {Parameter Name}"(DLV = Data Layer Variable)
  • 触发器:"CE - {Event Name}"(CE = Custom Event)
  • 标记:"GA4 - {Event Name}"

2. 错误处理

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. 批量操作

  • 首先创建所有变量
  • 然后创建触发器(它们可能会引用变量)
  • 最后创建标记(它们会同时引用变量和触发器)

4. 始终动态解析工作区 绝不要使用硬编码或缓存的 workspaceId。执行任何操作前,请调用:

const workspaces = await tagmanager.accounts.containers.workspaces.list({
  parent: `accounts/${accountId}/containers/${containerId}`
})
const workspaceId = workspaces.data.workspace[0].workspaceId

GTM 会在每次发布时删除并重新创建工作区,因此已存储的 ID 会过期。

参数提取技巧

提取参数时要灵活判断:

从 ID 属性中提取:

// id="cta_hero_get_started"
const [category, location, ...action] = id.split('_')
// category: "cta", location: "hero", action: ["get", "started"]

从类名中提取:

// className="btn btn-primary"
const isPrimary = className.includes('primary')
const type = isPrimary ? 'primary' : 'secondary'

从内容中提取:

// <button>Get Started</button>
const text = element.innerText // "Get Started"

从 href/目标地址中提取:

// <Link href="/pricing">
const destination = href // "/pricing"

// onClick={() => router.push('/signup')}
// Parse from handler → destination: "/signup"

脚本

scripts/gtm-api-client.js

用于创建变量/触发器/标记的核心 GTM API 封装器(从 gtm-setup-auto.js 的逻辑中提取)

scripts/create-variables.js

包含重复项检测的变量创建逻辑

scripts/create-triggers.js

用于自定义事件的触发器创建逻辑

scripts/create-tags.js

包含参数映射的 GA4 事件标记创建逻辑

scripts/implement-datalayer.js

分析跟踪计划,并使用 Edit 工具在代码中实现 dataLayer.push()

参考资料

references/datalayer-patterns.md

特定框架的 dataLayer 实现模式:

  • Next.js App Router('use client' 指令)
  • Next.js Pages Router
  • React(钩子、类组件)
  • Vue(组合式 API、选项式 API)
  • 原生 JavaScript
references/gtm-ui-guide.md

API 失败时的备用方案:GTM UI 手动操作说明

references/event-taxonomies.md

常见事件命名模式(object_action 与 action_object)

资源

assets/templates/saas.json

预构建的 SaaS 产品跟踪 GTM 配置:

  • trial_start、feature_usage、upgrade_click
  • account_created、plan_selected
assets/templates/ecommerce.json

预构建的电子商务跟踪 GTM 配置:

  • product_view、add_to_cart、checkout_start
  • purchase_complete、product_search

支持文件

  • template.md - 特定框架的 dataLayer 推送代码模式和 GTM API 负载模板
  • examples/sample.md - 示例实现输出,展示代码更改前后的对比以及控制台输出
assets/templates/lead-generation.json

预构建的潜在客户开发跟踪 GTM 配置:

  • form_start、form_submit、content_download
  • demo_request、newsletter_signup

执行清单

  • 已加载跟踪计划或已指定事件
  • 已验证 GTM API 凭据
  • 已检测框架
  • 已识别目标元素
  • 已在代码中实现 DataLayer 事件
  • 已通过 GTM API 创建变量
  • 已通过 GTM API 创建触发器
  • 已通过 GTM API 创建标记
  • 已创建容器版本
  • 已生成实现摘要
  • 已提供测试说明

常见问题

问:如果我没有跟踪计划怎么办? 答:先运行 gtm-strategy 技能来创建计划,或者手动指定事件,我们会负责实现。

问:不使用 GTM API 也能实现跟踪吗? 答:可以。我们会在代码中实现 dataLayer 事件,并提供手动配置 GTM UI 的说明。

问:这会覆盖现有的 GTM 配置吗? 答:不会。我们会检查现有的变量、触发器和代码,并对其进行更新。新配置会被添加,而不是替换现有配置。

问:能否只为特定事件实现跟踪? 答:可以。指定要实现的事件即可(例如,“只实现 cta_click 跟踪”)。

问:如果我的框架不受支持怎么办? 答:dataLayer.push 模式适用于任何 JavaScript 环境。我们会提供原生 JavaScript 实现。

问:在 GTM 中发布后,我的工作区 ID 变了。技能会因此出错吗? 答:不会。技能始终会通过 API 列出可用的工作区,并使用找到的第一个工作区,不论其 ID 是什么。发布后无需更新 gtm-config.json。

评论

支持 Markdown