主题
WellChina 数据分析接入规范
长期规范。每次新增功能 / 页面 / 交互都应回到本文档对照。
运行态配置(Property ID、后台清单、验证流程)见 实施方案。 决策依据(监控什么 / 不监控什么)见 监控策略调研。
版本: v2.0 适用范围: WellChina 主站(src/app/[locale]/*) 不适用: Admin 后台、API 路由
目录
- 核心原则
- 两框架职责边界
- 决策树:新功能如何接入
- 事件命名规范
- 事件参数规范
- 自定义维度治理
- 隐私与 Consent 规范
- 性能预算
- 新功能接入 Checklist
- PR 审查 Checklist
- Dev → Prod 环境工作流
- 常见错误模式
- 配额与成本管理
- 扩展路径
- 治理机制
- 已知 Gap & 后续 PR 计划
1. 核心原则
- 单一数据源 — 一个指标只归一个系统测量。不双写、不重复。
- 事件是公共 API — 事件名和参数一旦发布,就是下游报表、BigQuery、Looker 的契约。改名等同 breaking change。
- 每个事件都是一个决策 — 问"这个事件能回答什么业务问题?",答不出来就不要埋。
- 性能不妥协 — 任何 analytics 代码不得让 LCP 倒退 > 100ms,不得阻塞交互。
- 隐私优先 — 默认不采 PII;EEA 用户的 cookie 必须走 Consent Mode v2。
- 可回滚 — 任何事件都能不重新部署就禁用(清空环境变量 或 事件函数体置空)。
2. 两框架职责边界
2.1 职责分工表
| 能力 | 归属 | 为什么 |
|---|---|---|
| Page View / UV | GA4 | 免费、无限切片、和 Search Console 联动 |
| 流量来源 / UTM / 归因 | GA4 | 数据驱动归因模型 |
| 用户行为漏斗 | GA4 | Explorations 可视化漏斗 |
| 留存 / Cohort | GA4 | 内置 Cohort 报告 |
| 自定义业务事件 | GA4 | 25 参数/事件、500 事件/property、免费 |
| A/B 实验分析 | GA4 + BigQuery | 原始事件导出做 SQL 分析 |
| Core Web Vitals | Vercel Speed Insights | 数据更全、抗 adblock、自动路由归一化 |
| 性能回归定位 | Vercel Speed Insights | 可切到某次部署之后看数据 |
| 服务端响应时间 | Vercel Observability | 已内置 |
| 错误追踪 | 未选型(候选 Sentry) | 不在本规范范围 |
| 会话录屏 | 未选型(候选 Microsoft Clarity) | 见 §14 |
2.2 禁用清单
- ❌ 不在 GA4 里重复发 Web Vitals(LCP/INP/CLS)— Speed Insights 单一数据源
- ❌ 不为视频 play/pause 建自定义事件 — Enhanced Measurement 已覆盖
- ❌ 不装
@vercel/analytics— 与 GA4 重叠 >80% - ❌ 不用
@next/third-parties/google的GoogleAnalytics组件 — 会覆盖send_page_view: false造成双重上报(历史 bug,已改为手写 loader) - ❌ 不在 admin / api 路由发事件
- ❌ 不绕过
src/lib/analytics/events.ts直接调window.gtag
3. 决策树
渲染中…
简化版
| 新增场景 | 该做什么 |
|---|---|
| 加新页面 | RouteChangeTracker 自动 page_view,无需埋点 |
| 加新按钮(纯交互) | 不埋点 |
| 加新按钮(推进转化) | 加事件;按 §4 命名 |
| 加新 CTA | 复用原事件;需区分时加 variant 参数 |
| 加新表单 | generate_lead + lead_source 标来源 |
| 加新支付 / 订阅入口 | begin_checkout + purchase |
| 加新筛选器 | 通常不埋;核心漏斗一步时用 select_item + item_list_name |
具体"值不值得埋"的判断见 监控策略调研。
4. 事件命名规范
4.1 硬性规则
| 规则 | 值 |
|---|---|
| 字符集 | [a-z0-9_] 全小写 snake_case |
| 长度 | ≤ 40 字符 |
不以 ga_ / google_ / firebase_ 开头 | — |
| 动宾结构 | 动词_名词 或 名词_状态 |
| 避免复数 | 用单数(和 GA4 recommended 一致) |
4.2 命名风格
- 优先级 1:GA4 recommended events 全名照抄(不改字)
- 优先级 2:自定义用
domain_action或domain_action_object
GA4 recommended 全集:view_item、select_item、view_item_list、add_to_cart、remove_from_cart、view_cart、begin_checkout、add_payment_info、purchase、refund、generate_lead、search、sign_up、login、share、join_group。
| ✅ 好 | ❌ 差 |
|---|---|
chat_opened | chat(缺动作) |
locale_switched | changeLocale(camelCase) |
step_city_selected | city_step(动宾不清) |
guide_read_complete | read_completed_guide_on_page_visit(超长) |
4.3 WellChina 事件命名空间
源码清单见 src/lib/analytics/events.ts。扩展事件须事先加入本表并同步更新源码。
| 命名空间 | 事件 | 用途 |
|---|---|---|
| recommended | page_view view_item select_item view_item_list add_to_cart remove_from_cart view_cart begin_checkout purchase generate_lead search sign_up login share | GA4 官方 |
| step_ | step_category_selected step_pricing_viewed step_city_selected | 首页 3 步引导漏斗 |
| chat_ | chat_opened chat_start chat_message_sent(前 3 条)chat_message_received(每 convo 首次 agent 回复) | 聊天系统 |
| plan_ | plan_selected(付费 plan 点击 CTA 时,早于 begin_checkout) | 价格敏感度 |
| lead 归因闭环 | close_convert_lead(服务端 via Measurement Protocol,仅当 Stripe 支付成功且能匹配到 30 天内同 email 的 ContactInquiry) | lead → purchase 归因 |
| locale_ | locale_switched | 语言切换。region 已降级为 user_property(§16.14)不再作为 event |
| guide_ | guide_read_complete | 内容消费 |
4.4 强制复用
- 点击手术卡 / 医院卡 / 城市卡 →
select_item+item_list_name区分 - 任何"漏斗一步"→
step_*系列或begin_checkout - 任何"lead form 提交"→
generate_lead+lead_source区分
5. 事件参数规范
5.1 硬性规则
| 规则 | 值 |
|---|---|
| 每事件最多参数 | 25 |
| 参数名长度 | ≤ 40 字符,snake_case |
| 参数值(字符串)长度 | ≤ 100 字符 |
| 保留参数 | currency(ISO 4217 大写)、value(数字)、items(数组)、transaction_id |
undefined / null | trackEvent 自动过滤 |
5.2 标准参数字典
所有事件应尽量携带这些参数。需在报表切片的必须按 §6 注册为 Custom Dimension。
| 参数 | 类型 | 含义 | 示例 |
|---|---|---|---|
locale | string | 8 语言之一 | 'en' / 'zh' |
region | string | 10 地区之一 | 'CN' / 'US' |
city | string | 城市 slug | 'beijing' |
procedure_category | string | 10 类别 slug | 'dental' |
hospital_id | string | 医院 slug | 'peking-union-medical-college' |
lead_source | string | lead 来源 | 'contact_page' / 'chat' |
subscription_plan | string | Stripe 计划 | 'starter' / 'navigator' / 'concierge' |
step | number | 漏斗步骤 | 1 / 2 / 3 |
compare_size | number | 对比 cart size | 1 / 2 / 3 |
5.3 items 数组
GA4 电商 schema。结构见类型定义 GAItem。必须原生数组传入,不能 JSON.stringify(这是曾被修复的 bug)。
常用字段:item_id(slug,必填)、item_name(英文名,必填)、item_category(hospital / procedure / plan)、可选 price、location_id、index、item_list_name。
5.4 参数命名禁忌
| ❌ 差 | ✅ 好 |
|---|---|
hospitalId | hospital_id |
q | search_term |
cat | procedure_category |
lang | locale |
price(事件总价值时) | value |
currency: 'cny' | currency: 'CNY' |
6. 自定义维度治理
6.1 注册 / 不注册的判据
注册当且仅当:要在 GA4 报表 UI 或 Explorations 里看它作为维度切片。
不要注册:
- 高基数(> 500 unique)—— 会被合并到
(other)(如user_id/transaction_id) - 临时调试参数
- 能被内置维度覆盖的(
country/device_category)
6.2 注册流程
渲染中…
Scope:大多数 Event-scoped;长期属性(user_type、subscription_plan)用 User-scoped。
6.3 上限
GA4 标准 property:50 Event-scoped + 25 User-scoped + 50 custom metrics。当前使用 ~10,充裕。
6.4 退休流程
- 代码停发 → 2. 等 90 天确认无报表使用 → 3. GA4 Admin 归档(不能硬删)
7. 隐私与 Consent 规范
7.1 核心守则
- 默认不采 PII。邮箱、手机号、姓名、完整 IP 绝不作为参数
user_id必须 hash(SHA-256 前 32 位),实现见UserIdentity.tsx- EEA + UK 默认 denied,其他地区默认 granted
- Consent 变更通过
gtag('consent', 'update', ...)通知 - Speed Insights 不受 Consent 影响(不采 PII),无条件上报
EEA 国家列表与默认值矩阵见 src/lib/analytics/consent.ts。
7.2 参数 vs PII 判定
| 参数值 | PII? | 能用? |
|---|---|---|
user_id: 'abc123hash'(已 hash) | 否 | ✅ |
user_id: 'user@example.com' | 是 | ❌ |
email / phone | 是 | ❌ |
city: 'beijing' | 否 | ✅ |
locale: 'en' | 否 | ✅ |
search_term(可能含用户名) | 可能 | ⚠️ GA4 会有限脱敏 |
7.3 用户撤回同意
Footer 的 "Cookie preferences" 按钮(CookiePreferencesButton.tsx)清空 cookie + reload,ConsentBanner 重新出现。满足 GDPR Article 7(3)。
7.4 法律兜底
/privacy声明 GA4 + Speed Insights + 所有第三方处理者- 用户数据删除请求通过 GA4 User Deletion API 处理
8. 性能预算
8.1 数值目标(2026 年标准)
| 指标 | P75 目标 |
|---|---|
| LCP | ≤ 2.5s |
| INP | ≤ 200ms |
| CLS | ≤ 0.1 |
| FCP | ≤ 1.8s |
| Real Experience Score | ≥ 90 |
| GA script 对 LCP 的影响 | ≤ 100ms(相对基线) |
8.2 引入 analytics 代码的门槛
- 不在 hot path(每次渲染 / scroll)→ 必须 debounce / throttle
- 不在 render 里发事件 → 在
useEffect里 - 参数值 ≤ 100 字符,
items数组 ≤ 200 个
8.3 性能回归处置
发现(P75 LCP 连续 3 天 > 2.5s 或周环比恶化 > 15%)→ Speed Insights 按 route / 国家 / 设备 切片 → 关联 deploymentId 定位部署 → 修(next/image + priority、字体预加载、第三方脚本 lazyOnload)
9. 新功能接入 Checklist
设计阶段
- [ ] 已读 §2 职责边界 + §3 决策树
- [ ] 明确列出要埋的事件名 + 参数
- [ ] 事件能回答至少一个具体业务问题
- [ ] 优先复用 GA4 recommended events
- [ ] 无新 PII 参数
编码阶段
- [ ] 事件加到
events.ts作为具名函数 - [ ] 不直接调
window.gtag - [ ] 客户端组件标
'use client' - [ ] Server 页面的
view_item通过客户端 tracker 组件触发 - [ ] 参数名 snake_case
- [ ] 新 custom dimension 在 §5.2 + GA4 Admin 都登记
测试阶段
- [ ] 本地 dev + GA Debugger 扩展验证事件发出(Level 1)
- [ ] DebugView 确认事件 + 参数 + 值
- [ ] Preview 部署手工走 happy path(Level 2)
- [ ] Preview 跑 Lighthouse,LCP 无退化
上线后
- [ ] 48h 后 Realtime 事件计数 > 0
- [ ] 一周后 Speed Insights 新路由 CWV 在预算内
- [ ] Key Event 在 GA4 Admin 标记
10. PR 审查 Checklist
必查
- [ ] 事件名符合 §4.1
- [ ] 对齐 GA4 recommended events 或复用已有
- [ ] 参数符合 §5 + 无 PII
- [ ] 无直接
window.gtag调用 - [ ] admin / API 路由不被追踪
- [ ] 符合 §8 性能预算
拒绝合并的红线
- 🚫 新事件名不在 §4.3 命名空间且没更新文档
- 🚫 参数值含 email / phone / 姓名
- 🚫 绕过
events.ts直接写window.gtag(...) - 🚫 在 admin 路由发事件
- 🚫 Consent Mode v2 默认值被改(法务未确认)
- 🚫 添加
@vercel/analytics依赖
11. Dev → Prod 环境工作流
11.1 两个 Property
| Property | Measurement ID | 服务环境 |
|---|---|---|
| WellChina Production | G-J2B82S5Y38 | Vercel Production (wellchina.top) |
| WellChina Staging | G-J5X6RDJ135 | 本地 npm run dev + Vercel Preview |
两个 property 的 Enhanced Measurement、Custom Dimensions、Data Retention 必须完全一致。Search Console 链接仅 Production。
11.2 环境变量
本地 .env(私有仓库 track)或 .env.local(gitignored):
bash
NEXT_PUBLIC_GA_ID=G-J5X6RDJ135Vercel Dashboard:Production 和 Preview 各一条独立记录。
11.3 三级测试标准
| Level | 场景 | 工具 | 合格标准 |
|---|---|---|---|
| 1 — 本地 | npm run dev | GA Debugger 扩展 + GA4 Staging → DebugView | 事件 5 秒内可见 |
| 2 — PR | Vercel Preview URL | GA4 Staging → Realtime | 转化路径每步计数 > 0 |
| 3 — 生产 | wellchina.top | GA Debugger + GA4 Production → DebugView;Stripe test 全链路 | 核心转化完整 |
日常开发只跑 Level 1;Level 2 是 PR review 一部分;Level 3 是发布 checklist。
11.4 禁止操作
- 🚫 Production property 用于测试
- 🚫 本地
.env填G-J2B82S5Y38 - 🚫 两个 property Enhanced Measurement 不一致
- 🚫 Vercel Preview 环境变量填 Production ID
12. 常见错误模式
12.1 双重上报
- 症状:GA4 某事件计数翻倍
- 根源:Enhanced Measurement 的 "Page changes" 开着 +
<RouteChangeTracker>也发;或 React Strict Mode 双渲染 - 预防:永久关闭 Enhanced Measurement 的 "Page changes based on browser history events";
<RouteChangeTracker>内useRef去重(已内建)
12.2 参数查不到
- 症状:GA4 报表找不到新加的参数
- 根源:没注册 Custom Dimension
- 修:Admin → Custom definitions → Create(参数名大小写敏感)
12.3 DebugView 有 / Realtime 没有
- 症状:本地 DebugView 正常,生产 Realtime 无数据
- 根源:生产用了 Staging ID,或 Consent denied 导致 cookie-less pings
- 修:核对 Vercel 环境变量;确认 Consent 状态
12.4 user_id 被错设成明文 email
- 后果:违反 GDPR,立即修并联系法务
- 预防:
<UserIdentity>强制 SHA-256 hash;code review 阻断
12.5 Speed Insights 配额耗尽
- 症状:Vercel Dashboard Usage 到 10k data points
- 修:先确认
beforeSend过滤 admin/API;降sampleRate到 0.5 或 0.3;DAU 持续 > 1000 再考虑升 Pro
12.6 语言切换后 locale 丢失
- 症状:切到
/zh/...事件locale还是en - 根源:用了
window.location.href = ...而非router.push - 预防:优先
@/i18n/navigation的Link/useRouter;location.reload()是最后手段
13. 配额与成本管理
13.1 GA4 免费额度
- ≤ 10M events/月免费
- 免费 14 个月 data retention
- 免费 BigQuery Daily Export ≤ 1M events/日
- GA4 360($150k/年起)仅超大规模需要
预期:3 年内无需付费。
13.2 Speed Insights
| 档位 | 数据点 | 费用 |
|---|---|---|
| Hobby | 10,000/月 | 免费 |
| Pro | 25k base + 超量 | $10/月 + $0.65 / 1000 超出 |
DAU ~500 × ~5 dp = 75k/月 → Hobby 不够。应对:先跑一周看实际,爆了用 sampleRate: 0.3,DAU > 1000 再升 Pro。
13.3 BigQuery
- Daily Export 免费
- 存储 $0.02/GB/月(首 10 GB 免费)
- 查询 $5/TB(首 1 TB/月免费)
- WellChina 年产生 ~5 GB → 年成本 < $10
13.4 告警
- Vercel Spend Management 设 $30/月上限
- GA4 Data Retention 14 个月,过期自动清理
14. 扩展路径
渲染中…
| Level | 何时做 | 核心好处 |
|---|---|---|
| 1 | 接入 GA4 当周 | GA4 里看关键词 → 落地页 → 转化全链路 |
| 2 | 有 3 个月数据,GA4 UI 答不出 | 任意 SQL、和其他数据源 join |
| 3 | 转化率优化第二阶段 | 会话录屏 + 热力图 + Rage click |
| 4 | 非技术同学要定期看数据 | 自定义业务仪表盘 |
| 5 | DAU > 5000,要主动告警 | 性能告警 + APM 关联 |
| 6 | 规模化后按需 | — |
15. 治理机制
15.1 角色
| 角色 | 责任 |
|---|---|
| 数据 Owner(工程负责人兼任) | 本文档维护、事件命名空间管理、custom dimension 注册 |
| 工程师 | 按规范实施埋点、PR 自检、上线后验证 |
| Reviewer | 按 §10 审查 PR |
| 运营 | 提出业务问题、用 GA4 报表做决策 |
15.2 文档更新触发
以下情况必须更新本文档(影响架构时同步更新实施方案):
- 新增事件 → §4.3 命名空间
- 新增 custom dimension → §5.2 参数字典
- 修改 Consent 默认值
- 修改性能预算
- 更换工具栈
- 依赖库 breaking change
15.3 审计节奏
| 频率 | 审计项 |
|---|---|
| 每周 | Speed Insights Usage、GA4 Realtime 计数 |
| 每月 | DebugView 抽检事件、review PR checklist 遵守情况 |
| 每季度 | custom dimensions 使用情况、归档无用的、review 性能预算 |
| 每半年 | 工具栈回顾、考虑扩展 |
15.4 决策记录 (ADR)
所有大决策(换工具、废弃事件、大规模改名)写 ADR 到 docs/adr/(首条 ADR 时创建该目录)。模板:Context / Decision / Consequences / Alternatives。
15.5 事件退休流程
- 团队公告 3 周后停用
events.ts对应函数加@deprecatedJSDoc- 新 PR 不再引入
- 保留 90 天让 BigQuery 查询 / Looker 报表适应
- 删除事件 + GA4 归档 custom dimension
16. 已知 Gap & 后续 PR 计划
优先级依据 监控策略调研 第 8.3 节。按 P0/P1/P2/P3 顺序执行,不要一次全做。
已关闭
- 16.1
step_city_selected未接线 ✅ 2026-04-21 —HospitalListWithFilter加category?prop,城市 pill 选中时调用trackStepCitySelected - 16.4 ConsentBanner 撤回入口 ✅ 2026-04-21 —
CookiePreferencesButton挂在 Footer,8 语言已翻译 - 16.6 Sitemap + 多搜索引擎注册 ✅ 2026-04-21 —
src/app/sitemap.ts+robots.ts,189 个 canonical × 8 locale hreflang = ~1500 URL,每日 revalidate。Middleware matcher 后续补丁(2026-04-22):src/middleware.ts原来没排除.xml/.txt,导致 next-intl 中间件拦截/sitemap.xml返回 404;加上sitemap.xml|robots.txt|...|xml|txt到 matcher 负向前瞻后修复。搜索引擎注册:Google Search Console(DNS TXT 验证)/ Bing Webmaster(msvalidate.01meta)/ Yandex Webmaster(yandex-verificationmeta)/ Naver Search Advisor(naver-site-verificationmeta)全部在src/app/layout.tsx的metadata.verification.other里声明,Next.js 自动渲染到<head>。Baidu 按产品定位排除。各平台的 sitemap 提交是用户手动动作(Domain property 要填完整 URLhttps://www.wellchina.top/sitemap.xml) - 16.7 Production 环境变量错配 ✅ 2026-04-22 — 根因:之前创建的两条 Vercel env var 名字被填成了
Production/Preview(作用域被误解为变量名),Next.js 读不到 → fallback 到.env里 commit 的 Staging ID。修复:删错命名变量 + 新建两条正确命名NEXT_PUBLIC_GA_ID(Production=G-J2B82S5Y38/ Preview=G-J5X6RDJ135)+ no-cache redeploy。Smoke test 确认tid=G-J2B82S5Y38正确上报 - 16.8 删除
theme_toggled✅ 2026-04-22 — 按研究报告结论去掉零价值事件。events.ts的trackThemeToggle函数 +ThemeToggle.tsx的调用 + §4.3 命名空间表条目都已移除。历史数据保留 14 个月自然过期,GA4 Admin 无 Custom Dimension 需归档 - 16.9 确认 Custom Dimension 高基数审计 ✅ 2026-04-22 — 两个 Property 各 10 个 CD(
citycompare_sizehospital_idlead_sourcelocaleprocedure_categoryregionstepsubscription_planuser_type),基数均 ≤ 100,远低于 500 阈值。没有注册conversation_id/user_id/session_id/transaction_id等危险字段 - 16.10 China GFW LCP runbook ✅ 2026-04-22(降级关闭) — 产品定位决定:WellChina 核心用户是境外用户做来华医疗决策,不服务中国大陆本土用户。代码侧
next/script strategy="afterInteractive"已经使 gtag.js 异步加载,即使被墙也不阻塞 LCP。不跑 WebPageTest 北京节点测试,不做 runbook 文档。未来市场策略改变时重开
P0 — 立即(本周内)
(全部已关闭)
P1 — 2-4 周
16.2 列表卡片 select_item 接线 ✅ 2026-04-22(4 周时间盒,2026-05-20 回看)
实施:新建 src/components/analytics/SelectItemTracker.tsx 客户端 wrapper,用事件委托监听冒泡 click,读被点卡片祖先的 data-track-item-id / data-track-item-name / data-track-item-index 属性后 fire trackSelectItem。7 个列表全部接入:
/hospitals→hospitals_all/procedures→procedures_all/procedures/[category]→procedures_by_category/cities→cities_allHospitalListWithFilter(手术详情页内) →hospitals_by_procedure/search× 3 →search_hospitals/search_procedures/search_cities
顺带小改动:Card.tsx 的 CardProps 继承 React.HTMLAttributes 以透传 data-* / aria-*;Button.tsx 的 href 模式现在 forward onClick(服务 §16.11 同时启用)。
4 周时间盒条款:2026-05-20 前回看 GA4 Explore,若无人查询 select_item → 下一个 PR 移除 <SelectItemTracker> + 卡片 data-* + trackSelectItem 函数。回看 checklist 写进运营 onboarding。
16.11 新增 plan_selected ✅ 2026-04-22
实施:PricingCard Button 组件加 onClick,付费 plan(非 free)点击时调用 trackPlanSelected({ plan, priceUsd, locale }),发生在 begin_checkout 之前(用户点 Subscribe → 跳 /plans/intake → 通过 2 步向导再触发 begin_checkout)。免费 plan 的 CTA 导向 /procedures,无 plan_selected。Button 组件已扩展 href 模式下 onClick 透传到 Link。
16.12 新增 chat_message_received ✅ 2026-04-22
实施:useChat.ts Supabase realtime INSERT 订阅内,sender_role === 'agent' 分支加 sessionStorage dedup(key ga_chat_first_reply:{conversationId})后调用 trackChatMessageReceived。每个 conversation 只 fire 一次 —— admin 后续多条回复不重复上报。
16.13 启用 EM form_start ✅ 2026-04-22
依据:调研 §1.4 — 零代码成本的表单转化率分母。与 generate_lead 配对后可得"Contact 表单开始 → 提交"的流失率。
GA4 UI 现实(2025+):原来 form_start / form_submit 的独立子开关已被合并为一个 "Form interactions" 大开关,不能分别控制。接受 form_submit 会和 generate_lead 并存上报的事实。
操作步骤(两个 Property 各一次):
- GA4 Admin → Data Streams → 选 Stream → Enhanced measurement 齿轮
- Form interactions → 打开 ✅
- Save
关键配套动作:不要把 form_submit 标为 Key Event。转化数据以 generate_lead 为准 —— 它带 lead_source / has_procedure / has_plan_interest 等业务参数,而 form_submit 是泛化事件(包括搜索框、筛选等任何 form),只作为"分母"用。
验证:访问 wellchina.top/contact → focus 姓名输入框 → GA4 DebugView 应看到 form_start;完成提交应看到 form_submit + generate_lead 两个事件。
不需要代码改动 —— HTML <form> 元素会被 EM 自动识别。
16.14 region_switched 降级 ✅ 2026-04-22
实施:trackRegionSwitch 函数从 events.ts 删除;RegionContext.setRegion 去掉调用 + import;UserIdentity.tsx 引入 useRegion(),把 region 随 user_type 一起写入 gtag('set', 'user_properties', ...)。每次 region 切换后 location.reload() 重新跑 UserIdentity effect,user_property 自动更新。此后所有事件自动带上最新 region 作为用户属性,不再产生 region_switched 事件。
16.15 chat_message_sent 降频 ✅ 2026-04-22
实施:useChat.ts 的 sendMessage 里,trackChatMessageSent 包一层条件 visitorCount <= 3(visitorCount = messages.filter(m => m.sender_role === 'visitor').length + 1,含本次乐观消息)。messages 加入 useCallback 依赖列表。conversation 第 4 条及之后 visitor 消息不再上报 chat_message_sent。
P2 — 1-3 月
16.3 OAuth 登录 / 注册 ✅ 2026-04-22
实施:AuthContext.onAuthStateChange 的 SIGNED_IN 分支新增 trackAuthIfOAuth(user):读 user.identities[0].provider,若 provider 非 email 则按 user.created_at 距离现在是否 < 60 秒区分 sign_up / login 并传 method: 'google'。email 路径跳过,继续由 SignupForm / LoginForm 上报。sessionStorage key ga_auth_tracked:{userId} 防同 session 重复,登出时清除。events.ts 的 trackSignUp / trackLogin method 联合类型扩展为 'email' | 'google' | 'anonymous'。
16.16 close_convert_lead 闭环归因 ✅ 2026-04-22
实施(三处协同):
- Client(
IntakeWizard):startCheckout前从_gacookie 提取 GA4client_id,传给/api/checkout - Server(
/api/checkout):在 Stripe session metadata 写入gaClientId+leadId。leadId来自prisma.contactInquiry.findFirst({ email, createdAt: 最近 30 天 })—— 即:用户在 30 天内提交过 Contact 表单的 email 再下单,视为 lead 转化 - Server(
/api/webhook/stripe):checkout.session.completed成功后读 metadata,调用postGA4Event('close_convert_lead', ...)(新建src/lib/analytics/measurement-protocol.ts,通过 GA4 Measurement Protocol POST)
环境变量:GA_MP_API_SECRET —— GA4 Admin → Data Streams → Measurement Protocol API secrets 生成。两个 Property 各一个 secret,Vercel 按作用域分别配置:Production → Prod secret,Preview → Staging secret,local .env → Staging secret。
容错:MP POST 失败仅 console.warn,不影响 webhook 200 响应与订单创建。无 leadId(新用户直接下单)时不发事件,避免把所有 purchase 当作 lead 转化。
16.17 Server-side GTM / Vercel Edge proxy 🔵
依据:调研 §7.3 — iOS Safari ITP 把 _ga cookie 寿命限制到 7 天,导致境外核心用户(iOS 占比 30-50%)的回头客数据系统性低估。
实施:Vercel Edge Function 在 wellchina.top/_ga 代理到 google-analytics.com/g/collect。客户端改发本域。成本:部署复杂度 + 每次请求的 Edge 调用费。收益:cookie 以第一方身份更长寿命、回头客识别准确。
研究报告同时提到此方案能缓解中国 GFW,但产品定位已排除大陆市场(见 §16.10),此项收益不计入动机。
P3 — 3-6 月(视业务)
16.5 Consent Banner 可选优化
- 只对 EEA 显示(Vercel geo header 判断)
- Behavioral Modeling 需单日事件量 > 10K/日(当前达不到)
16.18 BigQuery Daily Export
MAU > 10K 时开。免费 1M events/日,解锁任意 SQL。
16.19 qualify_lead + CRM 集成
有销售团队 + CRM(HubSpot / Salesforce)后加。Measurement Protocol 从 admin 后台 fire。
永不做
见 调研 §5.6 / §8.2:mouse_move、hover、泛化 button_click、error_shown(用 Sentry)、add_shipping_info、add_payment_info、任何带 PII 的事件、admin 操作事件。
附录 A:快速参考
A1. 添加新事件 3 步
events.ts加具名函数- 调用处从
@/lib/analytics/eventsimport - 本文档 §4.3 命名空间表加一行
A2. 本地调试 3 件套
.env设 StagingNEXT_PUBLIC_GA_ID- 装 Chrome "GA Debugger" 扩展
- GA4 Admin → DebugView 实时查看
A3. 验收新埋点
- DebugView 看到事件名 + 所有参数
- Realtime 15 分钟内出现计数
- Lighthouse mobile LCP < 2.5s
A4. 5 问自检
- 事件名在 §4.3 里吗?
- 参数 snake_case?
- 非 PII?
- 不在 admin / API 路径?
- Consent Mode v2 默认值动过吗?
参考文档
- 实施方案 — 运行态配置清单
- 监控策略调研 — 监控什么的决策依据
- CLAUDE.md — 项目 UI Baseline + 技术栈
- GA4 Recommended Events
- Google Consent Mode v2
- Vercel Speed Insights
维护者: 数据 Owner 下次审阅: 2026-07-21(每季度)