mcpField
C
contentsquare-web-tag-install

contentsquare-web-tag-install

github.com/contentsquare营销与增长265 次安装1 周前更新
代码仓库

关于 contentsquare-web-tag-install

该 Skill 指导开发者在 Web 项目中安装 Contentsquare 跟踪标签,并通过浏览器进行验证。它提供按框架区分的设置步骤,并用向导报告检查标签加载、页面浏览事件和 CSP 问题。

主要功能

  1. 01按框架提供安装指导
  2. 02仅在浏览器环境初始化
  3. 03通过向导进行运行时验证
  4. 04检查页面浏览事件与 CSP
  5. 05指导处理验证失败

适用场景

  1. 01为 Web 应用添加 Contentsquare 跟踪
  2. 02检查标签加载及导航页面浏览事件
  3. 03诊断 Contentsquare 相关的 CSP 违规

安装

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

$npx skills add https://github.com/contentsquare/agents --skill contentsquare-web-tag-install

安装后在 Claude Code 中输入/contentsquare-web-tag-install确认已加载。

详细介绍

安装 Contentsquare 标签

你将协助开发者在其 Web 项目中安装并验证 Contentsquare 跟踪标签。 请从头到尾遵循本文档,不要跳过任何部分。

所有运行时验证都通过一条命令完成:

npx --yes @contentsquare/wizard@2 verify

该命令会启动真实浏览器,让开发者在应用中点击操作,并在同一会话中报告标签加载情况、首次页面浏览、导航时的页面浏览以及 CSP 问题。该命令按需由 npx 解析(首次运行后会缓存)——无需全局安装,你也无需自行操控浏览器。@2 固定到当前主版本系列,确保验证可重复,同时仍能获取补丁和次要修复。--yes 会跳过 npx 首次运行时的“Ok to proceed?” 安装提示,否则在尚未缓存该软件包的机器上,非交互式 Agent 会被阻塞。


规则(先阅读,并始终遵循)

  • 软件包名称必须是 @contentsquare/tag-sdk。函数名称必须是 injectContentsquareScript。唯一必需的选项是 clientId。不得替换、重命名或虚构其他名称。
  • injectContentsquareScript 必须仅在浏览器上下文中运行——绝不能在 SSR 期间运行。如果你要将其放入会在服务器上运行的文件中(Next.js Server Component、Nuxt server route、SvelteKit 的 +page.server.ts 等),则做法有误。
  • 标签 ID(又称哈希项目 ID)是一个小写十六进制字符串,长度约为 13 个字符(例如 81c677ba742d7)。如果你拿到的值看起来是普通十进制数字、电子邮件地址、URL 或其他形式——请停止操作并索取哈希项目 ID。绝不要自行哈希、转换、生成或猜测 ID。
  • 只能根据实际命令输出判断框架。如果检测结果不明确或缺少 package.json,请询问开发者。
  • 绝不要启动、重启或终止开发服务器。始终请开发者自行操作。
  • 除非 verify 报告违规,或你发现现有 CSP 缺少 Contentsquare 域名,否则不要修改 CSP。不要为没有 CSP 的项目预先添加 CSP 标头。
  • 只有确认软件包管理器并确认你位于项目根目录后,才能运行 npm install(或等效命令)。
  • 验证失败 2 次后,停止修改代码并向开发者寻求指导。
  • 如果项目没有 tsconfig.json,则下文所有文件路径和模板都使用 .js/.jsx 扩展名,而不是 .ts/.tsx。

完成标准——仅当以下条件全部满足时才算完成(均直接来自 verify):

  1. tagScriptLoaded: true——标签脚本 t.contentsquare.net/uxa/<tagId>.js 已加载。
  2. initialPageview: true——至少又发出了一次到 t.contentsquare.net 的请求。
  3. cspViolations: []——没有涉及 Contentsquare 域名的 CSP 违规。

不要仅凭“代码看起来没问题”就宣布成功。只有 verify 报告才算数。


开始之前——获取标签 ID

  1. 在开发者最初的指示中查找标签 ID(例如“安装 Contentsquare,标签 ID 为 81c677ba742d7”)。如果已提供,直接使用——不要再次询问。
  2. 如果项目中存在 .cs-wizard/state.json,读取其中的 tagId 并使用。
  3. 如果仍然没有,请询问:

    “你的 Contentsquare 标签 ID 是什么?它是作为 clientId 使用的十六进制字符串(例如 81c677ba742d7)。你可以在标签代码片段或 Settings 中找到它。”

你需要将此值作为 --tag-id <tagId> 传给 verify。


流程

  1. 安装——检测框架、安装 SDK 并添加初始化代码。
  2. 验证——运行一次 npx @contentsquare/wizard verify;由开发者浏览其应用。
  3. 修复 CSP——仅当 verify 报告 cspViolations 时执行。
  4. 重新验证——再次运行 verify,确认所有项目均正常。

步骤 1——安装标签

1.1 检测框架

检查项目,不要猜测:

cat package.json | grep -E '"next"|"nuxt"|"vue"|"react"|"@angular/core"|"svelte"|"@sveltejs/kit"|"vite"|"@contentsquare/'
ls package-lock.json yarn.lock pnpm-lock.yaml bun.lockb 2>/dev/null
ls tsconfig.json 2>/dev/null
ls src/app app src/pages pages 2>/dev/null
ls src/main.ts src/main.tsx src/index.ts src/index.tsx app/layout.tsx app/layout.jsx src/app/layout.tsx src/app/layout.jsx pages/_app.tsx pages/_app.jsx 2>/dev/null
grep -r "contentsquare\|injectContentsquareScript\|_uxa" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.html" -l 2>/dev/null | grep -v node_modules

确定以下信息:

  • 框架(优先级:Next.js > React、Nuxt > Vue、SvelteKit > Svelte、Angular、Vite)
  • App Router 或 Pages Router(仅适用于 Next.js)——检查是否存在 app/ 或 src/app/
  • TypeScript(存在 tsconfig.json)或 JavaScript
  • 包管理器(npm/yarn/pnpm/bun)
  • 是否已安装?→ 跳至步骤 2
1.2 与开发者确认

“我检测到你使用 [framework] 和 [package manager],采用 [TS/JS]。入口文件为 [file]。是否正确?”

确认前不要继续。如果还没有 tag ID,现在询问。

1.3 安装软件包并添加初始化代码
npm install @contentsquare/tag-sdk
# or: yarn add / pnpm add / bun add — match the detected package manager

将下方的 <TAG_ID> 替换为开发者的实际 tag ID。


Next.js — App Router — 在 layout 所在路径创建一个客户端组件(app/contentsquare.tsx 或 src/app/contentsquare.tsx):

'use client';
import { useEffect } from 'react';
import { injectContentsquareScript } from '@contentsquare/tag-sdk';

export function Contentsquare() {
  useEffect(() => {
    injectContentsquareScript({ clientId: '<TAG_ID>' });
  }, []);
  return null;
}

然后在根 layout 中添加 <Contentsquare />(同一目录):

import { Contentsquare } from './contentsquare';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Contentsquare />
        {children}
      </body>
    </html>
  );
}

Next.js — Pages Router — 在 pages/_app.tsx 中:

import { useEffect } from 'react';
import { injectContentsquareScript } from '@contentsquare/tag-sdk';
import type { AppProps } from 'next/app';

export default function App({ Component, pageProps }: AppProps) {
  useEffect(() => {
    injectContentsquareScript({ clientId: '<TAG_ID>' });
  }, []);
  return <Component {...pageProps} />;
}

React (Vite / CRA) — 在 src/main.tsx(或 src/index.tsx)中,位于 ReactDOM.createRoot 之前:

import { injectContentsquareScript } from '@contentsquare/tag-sdk';
injectContentsquareScript({ clientId: '<TAG_ID>' });

Vue (Vite) — 在 src/main.ts 中:

import { injectContentsquareScript } from '@contentsquare/tag-sdk';
injectContentsquareScript({ clientId: '<TAG_ID>' });

Nuxt 3 — 创建 plugins/contentsquare.client.ts(.client 后缀可确保仅在浏览器中运行):

import { injectContentsquareScript } from '@contentsquare/tag-sdk';

export default defineNuxtPlugin(() => {
  injectContentsquareScript({ clientId: '<TAG_ID>' });
});

Angular — 在 src/main.ts 中,位于 bootstrapApplication / platformBrowserDynamic().bootstrapModule(...) 之前:

import { injectContentsquareScript } from '@contentsquare/tag-sdk';
injectContentsquareScript({ clientId: '<TAG_ID>' });

SvelteKit — 在 src/routes/+layout.svelte 中:

<script lang="ts">
  import { onMount } from 'svelte';
  import { injectContentsquareScript } from '@contentsquare/tag-sdk';

  onMount(() => {
    injectContentsquareScript({ clientId: '<TAG_ID>' });
  });
</script>

<slot />

静态 HTML / 服务端渲染(Django、Rails、Laravel、PHP、WordPress,或不使用 JS 框架)——添加到 <head> 内:

<script src="https://t.contentsquare.net/uxa/<TAG_ID>.js" defer></script>

常见位置:Django → templates/base.html、Rails → app/views/layouts/application.html.erb、Laravel → resources/views/layouts/app.blade.php、WordPress → header.php。

如果你使用 _uxa API 设置自定义变量或虚拟页面浏览量,请改用 IIFE 加载器模式,以便在脚本加载前缓存命令:

 <script>
 (function(c,s,q,u,a,r,e){
   c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
   e=s.createElement(q);e.async=1;e.src=u;
   r=s.getElementsByTagName(q)[0];r.parentNode.insertBefore(e,r);
 })(window,document,'script','https://t.contentsquare.net/uxa/<TAG_ID>.js','_uxa');
 </script>

1.4 准备验证

请开发者启动开发服务器。切勿自行启动。然后继续执行步骤 2。


步骤 2 — 使用向导 CLI 进行验证

首次运行前,请确保项目的 .gitignore 中包含 .cs-wizard/——验证器会在此目录中写入报告 (last-report.json、last-browser-error.json),这些文件不应提交。如果缺少此条目,请添加。

在项目根目录运行验证器。传入 URL 和标签 ID,以免出现提示,并使用 --json,让标准输出提供干净、可供机器读取的报告(即 Agent 模式):

npx --yes @contentsquare/wizard@2 verify --url http://localhost:3000 --tag-id <TAG_ID> --json

URL 默认值因框架而异:Next.js / Nuxt / CRA → http://localhost:3000, Vite → http://localhost:5173,Angular → http://localhost:4200。

此命令会进行交互,并一直阻塞,直到开发者完成操作。 它会打开真实浏览器并等待。不要认为它卡住了,也不要取消或设置超时时间。 在前台运行,并等待它自行退出。

运行过程:

  1. 真实浏览器窗口会打开指定 URL,并在页面上方显示 Contentsquare 横幅。
  2. 告知开发者:“浏览器已打开。请浏览你的应用——等待首个页面加载,点击进入几个应用内路由,并在需要时登录。完成后,点击横幅中的 Done(完成)(或直接关闭窗口)。”
  3. 只有开发者点击 Done(完成)或关闭窗口后,命令才会结束并打印报告。

从标准输出中打印的 JSON 读取结果,或读取 .cs-wizard/last-report.json(每次运行都会写入)。退出代码:

代码含义
0pass 或 pass-with-recommendation
1fail(报告已运行),或浏览器因未知原因启动失败({"error":"BROWSER_LAUNCH_FAILED"})
2未找到浏览器引擎({"error":"NO_BROWSER"})
3已安装浏览器,但缺少系统库({"error":"MISSING_LIBS"})
4已安装浏览器,但无法启动,例如企业策略限制或配置文件已在使用中({"error":"BLOCKED_LAUNCH"})
5没有图形显示环境(无头 Linux 设备);verify 需要可见窗口({"error":"NO_DISPLAY"})

请将以上情况视为正常的报告或环境结果,而非崩溃。对于任何非零的浏览器环境故障(2–5),--json 模式会在标准输出中打印 {"error":"<CODE>"} 对象,写入 .cs-wizard/last-browser-error.json 记录文件,并在标准错误输出中打印操作指南。请参阅下文的如果无法获取浏览器。

如果无法获取浏览器

如果 verify 以代码 2–5 退出,说明无法获取可用的浏览器。在 --json 模式下,stdout 会包含 {"error":"<CODE>"},stderr 会输出对应的修复建议。根据代码采取相应措施:

退出代码 / 错误含义处理方法
2 NO_BROWSER未安装浏览器引擎。征得开发者同意后,使用 --install-browser 重新运行(见下文)。
3 MISSING_LIBS已安装浏览器,但缺少 OS 库(在精简版 Linux 上很常见)。下载无法解决此问题。请开发者运行 sudo npx playwright-core install-deps chromium,然后重新运行步骤 2。
4 BLOCKED_LAUNCH浏览器已存在,但拒绝启动(企业策略限制,或配置文件已在使用中)。请开发者关闭所有 Chrome/Edge 窗口后重试;或安装捆绑的引擎,再使用 --install-browser 重新运行。
5 NO_DISPLAY正在没有显示器的无头 Linux 设备上运行;verify 需要可见窗口。开发者必须在有图形显示器的机器(自己的桌面设备)上运行 verify。它无法在无头环境下运行。

对于 NO_BROWSER(2),请征求开发者同意:

“验证器需要浏览器引擎,但未找到。是否允许我下载 Chromium(约 150 MB,一次性下载)?”

如果开发者同意,使用安装标记重新运行:

npx --yes @contentsquare/wizard@2 verify --url <url> --tag-id <TAG_ID> --json --install-browser

如果下载因企业代理而失败,CLI 会输出需要设置的代理环境变量(HTTPS_PROXY、NODE_EXTRA_CA_CERTS、PLAYWRIGHT_DOWNLOAD_HOST);将这些信息转告开发者,然后重新运行。

根据报告采取相应措施
报告操作
result: "pass"确定性检查(标签加载、首次页面浏览、CSP)均正常。完成前仍需评估下方的导航跟踪。
result: "pass-with-recommendation"标签可用,但发现了 CSP 违规。原样展示 recommendation,然后进入步骤 3。同时评估下方的导航跟踪。
tagScriptLoaded: false标签从未加载。确保 injectContentsquareScript 在客户端运行(使用 useEffect/onMount/.client.ts),并确认已安装该程序包。重新运行步骤 2。
initialPageview: false(脚本已加载)确认标签 ID 正确且项目处于活动状态。重新运行步骤 2。
tagIdMismatch: true标签 URL 使用的 ID 与 --tag-id 不同。修复代码中的 clientId。重新运行步骤 2。
cspViolations 非空进入步骤 3。
评估导航跟踪情况(由你判断——此项不在 result 中)

verify 会将导航作为原始证据报告,而不是评分检查:它会提供两组按时间排序的原始数据流,由你判断应用内导航是否被跟踪。并非所有应用都适用同一种 URL 规范化方式(路径路由、类似 /app#about 的哈希路由、类似 /app?tab=about 的查询参数路由),因此工具会将判断留给你。

  • navigations[] — 开发者执行的每次导航,包含完整 URL(保留哈希和查询参数)、type(完整页面加载 / MPA 时为 load,SPA 路由更改时为 pushState / replaceState / popstate / hashchange)、top 标记(true = 主框架,false = 位于 iframe 内)以及 ts。
  • pageviewBeacons[] — 标签实际触发的每次页面浏览事件,包含标签报告的 URL(url)和 ts。这是标签自身对“页面”的定义。

判断方法:

  1. 没有记录到导航(navigations 为空,或仅有初始 load): 开发者没有尝试应用内导航,因此未对此进行测试。请明确说明这一点——不要声称导航跟踪有效或失效。

  2. 优先关注主框架导航(top: true)。top: false 的条目发生在 iframe 内——可能是应用本身(有些应用运行在 iframe 中),也可能只是第三方嵌入内容(广告、视频、聊天、支付组件)。只有当 pageviewBeacons[] 中有条目报告了相同的 iframe URL 时,才将 top: false 导航视为应用导航;否则它们几乎肯定只是嵌入内容,应予以忽略。

  3. 开发者访问的每个不同页面都应有对应的页面浏览事件。 按意图关联,而非要求字符串完全相同:

    • 页面浏览事件报告的 url 与导航 URL 匹配(完全匹配,或匹配能标识该应用页面的部分路由信息)→ 该导航已被跟踪。
    • 当两边 URL 格式不同,页面浏览事件的 ts 紧随导航的 ts 出现,是有力的佐证。
  4. 完整页面(MPA)导航(type: "load"):每次完整加载都会重新加载标签,并应产生各自的页面浏览事件——预计每次加载大致对应一个事件。

  5. SPA / 哈希 / 查询参数导航(pushState/replaceState/popstate/hashchange,或 URL 仅 #… 或 ?… 不同):如果开发者在这些页面间切换,但标签没有为这些页面触发新的页面浏览事件,则标签可能未跟踪 URL 更改。请原样给出以下建议:

    有些应用内导航没有触发页面浏览事件。如果这是单页应用,请在 Contentsquare 应用中启用“Tracking URL Changes”(Project and Users → Tracking URL Changes)。

    如果应用纯粹通过哈希或查询字符串进行路由,请指出 Contentsquare 项目中的 URL 更改跟踪可能也需要配置为将它们视为不同的页面。

  6. 只有在证据表明存在缺漏时才给出建议。如果每个导航到的页面都有匹配的页面浏览事件,则导航跟踪正常——请明确说明。

  7. 有疑问时,不要猜测——查看代码。 如果关联情况不明确(URL 对不上、时间不清楚、路由方式不寻常,或应用运行在 iframe 中),请先检查应用的路由设置,再得出结论。查看路由器配置和导航代码(例如 createRouter/路由定义、哈希模式与历史模式、<a> 与客户端导航链接组件、重定向/守卫、应用是否挂载在 iframe 中),以了解观察到的现象。建议应基于代码的实际行为,而非假设。


第 3 步 — 修复 CSP(仅当 verify 报告了违规时)

3.1 查找现有 CSP
grep -rn "Content-Security-Policy\|contentSecurityPolicy" next.config.* middleware.* 2>/dev/null
grep -rln "Content-Security-Policy" --include="*.html" --include="*.ejs" --include="*.hbs" --include="*.blade.php" --include="*.erb" . 2>/dev/null | grep -v node_modules
cat package.json | grep -E '"helmet"|"csp-header"|"content-security-policy"' 2>/dev/null
3.2 添加 Contentsquare 域名

在项目现有指令后追加,切勿替换:

script-src:  'unsafe-inline' *.contentsquare.net app.contentsquare.com
connect-src: *.contentsquare.net *.contentsquare.com
img-src:     *.contentsquare.net

按照项目已有的格式应用这些指令(Next.js headers()、中间件、<meta> 标签、 nginx、helmet)。保留所有现有值。

示例(Next.js next.config.ts headers):

"script-src 'self' 'unsafe-inline' *.contentsquare.net app.contentsquare.com",
"connect-src 'self' *.contentsquare.net *.contentsquare.com",
"img-src 'self' *.contentsquare.net",
3.3 重新验证

请开发者重启开发服务器,使新标头生效,然后返回步骤 2 再次运行 verify。确认 cspViolations 现在为空。


成功

当 verify 返回 result: "pass"(或 pass-with-recommendation),且你已 评估导航跟踪后,报告:

✅ Contentsquare setup complete!

- Tag installed: <framework> via @contentsquare/tag-sdk
- Tag script loading: ✓
- First pageview sent: ✓
- Navigation tracking: <your assessment — see below>
- CSP: <no issues / fixed>

如果报告了 CSP 违规,请逐字添加 recommendation。如果你的 导航评估发现 SPA/hash/query 导航未被跟踪,请逐字添加 跟踪 URL 更改建议。

导航跟踪行的措辞方式(避免误导开发者)

verify 提供的是原始证据,而非分数:navigations[](开发者 访问过的页面)和 pageviewBeacons[](标签报告的页面浏览)。请自行关联两者, 据此推导这行内容——切勿编造 pageviews sent 计数。

  • 表述为已覆盖的页面,例如“你访问的每个页面都触发了页面浏览”, 或指出具体哪些页面未触发。不要说“发送了 N 次页面浏览”—— 这会混淆页面与网络信标,让开发者困惑。
  • 列出 navigations[].url 中的页面,并与 pageviewBeacons[].url 关联。
  • 即使开发者多次访问某个页面,也只计一次——原始 数据流可能包含重复项以及 replaceState/load 突发;汇总时请合并。
  • 如果 navigations 为空(或只有初始 load),请说明 未测试应用内导航,因此也未测试导航跟踪——不要将其报告为 通过或失败。

故障排除

问题解决方案
标签未加载确保 injectContentsquareScript 仅在客户端运行(useEffect、onMount、.client.ts)。
injectContentsquareScript is not a function确认已安装 @contentsquare/tag-sdk 且导入正确。
verify 未记录导航开发者必须先实际点击应用内路由,然后再点击 Done。
浏览器无法启动使用 --install-browser 重新运行,或安装 Google Chrome。
修复后 CSP 错误仍存在必须重启开发服务器,才能提供新标头。
违规源自 .contentsquare.com将 *.contentsquare.net 和 *.contentsquare.com 都添加到 connect-src。

评论

支持 Markdown