mcpField
G
gtm-setup

gtm-setup

github.com/cognyai营销与增长11149 次安装2 周前更新
代码仓库

关于 gtm-setup

gtm-setup 是 Google Tag Manager 事件跟踪参考技能,面向需要实现跟踪或配置标签、触发器和变量的营销人员与开发者,并提供示例和排错指导。

主要功能

  1. 01dataLayer 事件示例
  2. 02触发器与变量参考
  3. 03GA4 标签配置指导
  4. 04调试与故障排查
  5. 05实施最佳实践

适用场景

  1. 01设置电商事件跟踪
  2. 02配置 SPA 页面变化触发器
  3. 03在 GTM Preview 中调试标签
  4. 04将 dataLayer 值映射到 GA4 事件

MCP 相关

如果可用 Cogny GTM MCP 工具,该技能可检查 GTM 容器中的标签、触发器和变量。

安装

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

$npx skills add https://github.com/cognyai/claude-code-marketing-skills --skill gtm-setup

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

详细介绍

GTM 事件跟踪与设置参考

Google Tag Manager 事件跟踪完整参考指南,包括 dataLayer 基础知识、触发器和变量类型、GA4 标签配置、调试模式以及实施最佳实践。

完整文档:https://cogny.com/docs/gtm-event-tracking

用法

/gtm-setup                              # Full GTM reference overview
/gtm-setup dataLayer                    # dataLayer fundamentals and syntax
/gtm-setup purchase                     # Show purchase event dataLayer.push()
/gtm-setup triggers                     # All trigger types explained
/gtm-setup variables                    # All variable types explained
/gtm-setup tags                         # GA4 tag configuration
/gtm-setup debug                        # Debug mode and troubleshooting
/gtm-setup best practices               # Naming conventions, organization
/gtm-setup common mistakes              # Race conditions, missing data, duplicates

说明

你是 Google Tag Manager 专家。请使用此参考帮助用户实施事件跟踪、配置标签/触发器/变量、调试 GTM 问题并遵循最佳实践。

用户提问时,请查找下方的相关章节,并提供准确、可操作且可直接使用的代码片段。

如果用户提供了具体主题作为参数,请重点介绍该主题。否则,请概述 GTM 概念,并询问用户需要什么帮助。

如果有 Cogny GTM MCP 工具可用,请使用这些工具检查用户实际的 GTM 容器,列出其标签/触发器/变量,并根据其真实配置提供建议。


dataLayer 基础知识

什么是 dataLayer?

dataLayer 是一个 JavaScript 数组,充当网站与 GTM 之间的消息总线。将对象推送到 dataLayer 后,GTM 会读取这些对象以触发触发器并填充变量。

初始化

在 GTM 代码段之前声明 dataLayer,以捕获早期推送的数据:

<script>
  window.dataLayer = window.dataLayer || [];
</script>

dataLayer.push() 语法
// Push data AND fire a trigger (event key is required for trigger evaluation)
dataLayer.push({
  'event': 'custom_event_name',
  'key1': 'value1',
  'key2': 'value2'
});

// Push data without firing a trigger (no 'event' key)
dataLayer.push({
  'user_type': 'premium',
  'user_id': '12345'
});
对象持久化与合并

后续推送的值会覆盖先前的值。嵌套对象采用浅合并(会替换整个嵌套对象,而非进行深度合并):

dataLayer.push({ 'user': { 'name': 'John', 'plan': 'free' } });
dataLayer.push({ 'user': { 'plan': 'premium' } });
// Result: user = { plan: 'premium' } — user.name is GONE
清除过期数据(对电商至关重要)

在电商事件之前始终推送 null,以防过期数据造成污染:

dataLayer.push({ ecommerce: null });
dataLayer.push({
  'event': 'view_item',
  'ecommerce': {
    'items': [{ 'item_id': 'SKU-001', 'item_name': 'Blue T-Shirt', 'price': 29.99 }]
  }
});

常见的 dataLayer 事件

page_view
dataLayer.push({
  'event': 'page_view',
  'page_location': window.location.href,
  'page_title': document.title,
  'page_referrer': document.referrer,
  'content_group': 'blog'
});

对于 SPA(React、Next.js、Vue),请在路由变更时触发:

useEffect(() => {
  dataLayer.push({
    'event': 'page_view',
    'page_location': window.location.href,
    'page_title': document.title
  });
}, [location.pathname]);
purchase
dataLayer.push({ ecommerce: null });
dataLayer.push({
  'event': 'purchase',
  'ecommerce': {
    'transaction_id': 'T-20250211-001',
    'value': 149.97,
    'tax': 12.50,
    'shipping': 5.99,
    'currency': 'USD',
    'coupon': 'SUMMER20',
    'items': [
      {
        'item_id': 'SKU-001',
        'item_name': 'Blue T-Shirt',
        'item_brand': 'BrandName',
        'item_category': 'Apparel',
        'item_category2': 'T-Shirts',
        'item_variant': 'Blue',
        'price': 29.99,
        'quantity': 2
      },
      {
        'item_id': 'SKU-045',
        'item_name': 'Running Shoes',
        'item_brand': 'BrandName',
        'item_category': 'Footwear',
        'item_variant': 'Black/Size-10',
        'price': 89.99,
        'quantity': 1
      }
    ]
  }
});
add_to_cart
dataLayer.push({ ecommerce: null });
dataLayer.push({
  'event': 'add_to_cart',
  'ecommerce': {
    'currency': 'USD',
    'value': 29.99,
    'items': [{
      'item_id': 'SKU-001',
      'item_name': 'Blue T-Shirt',
      'item_brand': 'BrandName',
      'item_category': 'Apparel',
      'price': 29.99,
      'quantity': 1
    }]
  }
});
remove_from_cart
dataLayer.push({ ecommerce: null });
dataLayer.push({
  'event': 'remove_from_cart',
  'ecommerce': {
    'currency': 'USD',
    'value': 29.99,
    'items': [{
      'item_id': 'SKU-001',
      'item_name': 'Blue T-Shirt',
      'price': 29.99,
      'quantity': 1
    }]
  }
});
view_item
dataLayer.push({ ecommerce: null });
dataLayer.push({
  'event': 'view_item',
  'ecommerce': {
    'currency': 'USD',
    'value': 29.99,
    'items': [{
      'item_id': 'SKU-001',
      'item_name': 'Blue T-Shirt',
      'item_brand': 'BrandName',
      'item_category': 'Apparel',
      'price': 29.99
    }]
  }
});
view_item_list
dataLayer.push({ ecommerce: null });
dataLayer.push({
  'event': 'view_item_list',
  'ecommerce': {
    'item_list_id': 'category_apparel',
    'item_list_name': 'Apparel',
    'items': [
      { 'item_id': 'SKU-001', 'item_name': 'Blue T-Shirt', 'index': 0, 'price': 29.99 },
      { 'item_id': 'SKU-002', 'item_name': 'Red T-Shirt', 'index': 1, 'price': 29.99 }
    ]
  }
});
begin_checkout
dataLayer.push({ ecommerce: null });
dataLayer.push({
  'event': 'begin_checkout',
  'ecommerce': {
    'currency': 'USD',
    'value': 149.97,
    'coupon': 'SUMMER20',
    'items': [
      { 'item_id': 'SKU-001', 'item_name': 'Blue T-Shirt', 'price': 29.99, 'quantity': 2 },
      { 'item_id': 'SKU-045', 'item_name': 'Running Shoes', 'price': 89.99, 'quantity': 1 }
    ]
  }
});
form_submit
dataLayer.push({
  'event': 'form_submit',
  'form_id': 'contact_form',
  'form_name': 'Contact Us',
  'form_destination': '/thank-you'
});
generate_lead
dataLayer.push({
  'event': 'generate_lead',
  'currency': 'USD',
  'value': 50.00,
  'lead_source': 'contact_form'
});
sign_up / login
dataLayer.push({ 'event': 'sign_up', 'method': 'google' });
dataLayer.push({ 'event': 'login', 'method': 'email' });
search
dataLayer.push({
  'event': 'search',
  'search_term': 'blue t-shirt',
  'search_results_count': 42
});
scroll(自定义)
dataLayer.push({
  'event': 'scroll',
  'percent_scrolled': 90
});
视频事件
// video_start
dataLayer.push({
  'event': 'video_start',
  'video_title': 'Product Demo',
  'video_url': 'https://youtube.com/watch?v=abc123',
  'video_provider': 'youtube',
  'video_duration': 180
});

// video_progress
dataLayer.push({
  'event': 'video_progress',
  'video_title': 'Product Demo',
  'video_percent': 50,
  'video_current_time': 90,
  'video_duration': 180
});

// video_complete
dataLayer.push({
  'event': 'video_complete',
  'video_title': 'Product Demo',
  'video_duration': 180
});

触发器类型

页面浏览触发器
子类型触发时机用例
页面浏览gtm.js(立即)GA4 配置标签、同意状态检查
DOM 就绪gtm.dom(DOM 已解析)读取 DOM 元素的标签
窗口已加载gtm.load(所有资源已加载)依赖图片/脚本的标签

可按 Page Path、Page Hostname 或 Page URL 筛选。

点击触发器
子类型触发时机用例
所有元素点击任意元素按钮、div、图片
仅链接点击 <a> 元素外部链接、下载

可用变量:Click Element、Click Classes、Click ID、Click Target、Click URL、Click Text。

自定义事件触发器

当特定的 event 值被推送到 dataLayer 时触发。将 Event Name 设置为与 event 键值匹配。支持正则表达式(例如 form_submit.*)。

dataLayer.push({ 'event': 'form_submit' });
// Fires trigger where Event Name = "form_submit"
元素可见性触发器

元素进入视口时触发。

设置说明
选择方法CSS 选择器或元素 ID
触发时机每页一次/每个元素一次/每次
最小可见比例默认为 50%
最小屏幕显示时长毫秒
计时器触发器

按设定的间隔(毫秒)触发。可设置上限,以限制触发次数。

滚动深度触发器

在指定的滚动阈值(百分比或像素)触发。支持垂直和水平滚动。

变量:Scroll Depth Threshold、Scroll Depth Units、Scroll Direction。

YouTube 视频触发器

内置支持嵌入式 YouTube 视频。捕获:开始、完成、暂停、拖动进度、缓冲、进度(可配置阈值)。

变量:视频提供方、视频状态、视频 URL、视频标题、视频时长、视频当前时间、视频百分比、视频是否可见。

表单提交触发器

在表单提交时触发。选项:等待代码(将提交延迟最多 2000ms)、检查验证(仅在通过浏览器验证时触发)。

变量:表单元素、表单类名、表单 ID、表单目标、表单 URL、表单文本。

历史记录更改触发器

在 URL 片段更改或 pushState/replaceState 时触发。对 SPA 至关重要。

变量:新的历史记录片段、旧的历史记录片段、新的历史记录状态、旧的历史记录状态、历史记录来源。

触发器组

组合多个触发器。只有当组中的所有触发器在页面生命周期内至少触发过一次时,代码才会触发。

变量类型

数据层变量

按键名从 dataLayer 读取值。对于嵌套值,请使用点号表示法(例如,ecommerce.transaction_id)。始终使用 Version 2。

JavaScript 变量

读取全局 JS 变量(例如,document.title、navigator.language)。

DOM 元素变量

通过 CSS 选择器或 ID 读取 DOM 元素的文本内容或属性。

URL 变量

提取 URL 组件:完整 URL、协议、主机名、端口、路径、查询(可选查询键)、片段。

常量变量

存储固定值。用于在多个代码之间共享的 Measurement ID、Pixel ID 和配置字符串。

自定义 JavaScript 变量

运行匿名函数并返回其值:

// Get viewport width
function() {
  return window.innerWidth;
}
// Classify page type from URL
function() {
  var path = window.location.pathname;
  if (path === '/') return 'homepage';
  if (path.indexOf('/product/') === 0) return 'product';
  if (path.indexOf('/category/') === 0) return 'category';
  if (path.indexOf('/blog/') === 0) return 'blog';
  if (path.indexOf('/checkout') === 0) return 'checkout';
  return 'other';
}
// Read a cookie
function() {
  var match = document.cookie.match(new RegExp('(^| )user_segment=([^;]+)'));
  return match ? match[2] : undefined;
}
查找表变量

将输入值(来自另一个变量)映射到输出值。例如:页面路径 / 映射为 Homepage,/pricing 映射为 Pricing。

正则表达式表变量

与查找表类似,但使用正则表达式模式。例如:^/product/.* 映射为 Product Page。支持捕获组和大小写敏感设置。

代码类型

GA4 配置代码

设置 GA4 测量数据流。在所有页面触发。

设置描述
Measurement IDG-XXXXXXXXXX(使用常量变量)
Send page_view加载时自动发送 page_view
Fields to Setdebug_mode、send_page_view、user_id
User Properties用户级维度
GA4 事件代码

向 GA4 发送自定义事件。

设置描述
Configuration Tag你的 GA4 配置代码
Event NameGA4 事件名称(例如,generate_lead)
Event Parameters键值对(例如,transaction_id、value)
自定义 HTML 代码

运行任意 HTML/JavaScript。始终使用 try/catch 包裹:

<script>
  (function() {
    try {
      thirdPartySDK.track('event', { value: {{DLV - Value}} });
    } catch (e) {
      console.warn('GTM Custom HTML error:', e);
    }
  })();
</script>
自定义图片代码

触发像素请求(1x1 图片)。使用跟踪参数配置图片 URL。启用缓存清除。

内置变量

点击变量

点击元素、点击类名、点击 ID、点击目标、点击 URL、点击文本

表单变量

表单元素、表单类名、表单 ID、表单目标、表单 URL、表单文本

页面变量

页面 URL、页面主机名、页面路径、引荐来源

滚动变量

滚动深度阈值、滚动深度单位、滚动方向

视频变量

视频提供方、视频状态、视频 URL、视频标题、视频时长、视频当前时间、视频百分比、视频是否可见

实用工具变量

事件、环境名称、容器 ID、容器版本、HTML ID、随机数、调试模式

调试模式

GTM 预览/调试

在 GTM 工作区中点击“Preview”。Tag Assistant 会打开并显示:

  • 每个事件触发的代码 / 未触发的代码
  • 每个事件发生时的 dataLayer 状态
  • 变量及其解析后的值
控制台检查
// View entire dataLayer
console.table(dataLayer);

// Filter for specific events
dataLayer.filter(function(item) { return item.event === 'purchase'; });

// Watch pushes in real time
(function() {
  var orig = dataLayer.push;
  dataLayer.push = function() {
    console.log('dataLayer.push:', arguments[0]);
    return orig.apply(dataLayer, arguments);
  };
})();
GA4 DebugView

在 GA4 Config 代码的字段中添加 debug_mode: true,然后前往 GA4 Admin > DebugView 查看事件。

网络面板

在 DevTools 网络面板中按 collect 筛选,查看 GA4 请求。验证负载参数。

最佳实践

命名规范
元素规范示例
标签[Platform] - [Action] - [Detail]GA4 - Event - Purchase
触发器[Type] - [Condition]CE - form_submit
变量[Type prefix] - [Name]DLV - Transaction ID
自定义事件snake_casegenerate_lead
文件夹按平台或功能分类GA4、Meta、Consent
文件夹组织
GA4/
  GA4 - Config - All Pages
  GA4 - Event - Purchase
  GA4 - Event - Add to Cart
Meta/
  Meta - Pixel - Base Code
  Meta - Event - Purchase
Consent/
  HTML - Consent Banner Init
  HTML - Consent Mode Update
工作区管理
  • 为每个项目使用功能工作区(例如,Q1-2025-GA4-ecommerce)
  • 创建版本前始终先预览
  • 删除或合并未使用的工作区
版本控制
  • 在重大更改前后创建版本
  • 编写描述性版本名称:“v42 - 添加了 GA4 电商结账漏斗”
  • 如果发布后出现问题,请回滚
标签排序

使用标签排序,确保设置标签先于依赖它的标签触发。如果同一触发器上的顺序很重要,请使用标签触发优先级(数字越大,越先触发)。

Consent Mode v2
// Default (before user choice)
dataLayer.push({
  'event': 'consent_default',
  'consent': {
    'ad_storage': 'denied',
    'analytics_storage': 'denied',
    'ad_user_data': 'denied',
    'ad_personalization': 'denied'
  }
});

// After user grants consent
dataLayer.push({
  'event': 'consent_update',
  'consent': {
    'ad_storage': 'granted',
    'analytics_storage': 'granted',
    'ad_user_data': 'granted',
    'ad_personalization': 'granted'
  }
});

常见错误

1. 竞态条件

标签在 dataLayer 包含所需数据之前触发。解决方法:使用与特定 event 推送关联的自定义事件触发器,而非页面浏览触发器。

2. 触发器触发不正确

标签在所有页面触发,而不是仅在特定页面触发。解决方法:始终添加触发器过滤条件(例如,Page Path 等于 /thank-you)。

3. 缺少电商数据空值重置

之前推送的陈旧数据污染了事件。解决方法:在电商事件前始终执行 dataLayer.push({ ecommerce: null })。

4. 标签重复

同一事件被发送多次。原因:存在多个触发器、条件过于宽泛或触发选项错误。解决方法:使用“每页一次”,或检查触发器条件。

5. 自定义 HTML 导致页面故障

自定义 HTML 中的 JS 错误会阻止其他标签运行。解决方法:将所有自定义 HTML 包装在 try/catch 中。

6. 数据层变量返回 Undefined

原因:键名不匹配(区分大小写)、触发器触发后才推送数据、DLV 版本错误或点号路径不正确。

7. 未跟踪 SPA 页面浏览

未捕获路由更改。解决方法:使用历史记录更改触发器,或在路由更改时推送自定义 page_view 事件:

// Next.js App Router
'use client';
import { usePathname } from 'next/navigation';
import { useEffect } from 'react';

export function GTMPageView() {
  const pathname = usePathname();
  useEffect(() => {
    dataLayer.push({
      'event': 'page_view',
      'page_location': window.location.href,
      'page_title': document.title
    });
  }, [pathname]);
  return null;
}
8. 跨域跟踪问题

用户在不同域名下被计为新会话。解决方法:在 GA4 Config 标签中配置跨域链接器,或前往 GA4 Admin > Data Streams > Configure your domains 进行配置。

9. 预览流量导致分析数据膨胀

解决方法:添加阻止型触发器,条件为 Debug Mode 等于 true;或通过 traffic_type 参数过滤内部流量。

资源

评论

支持 Markdown