关于 contentsquare-web-tag-install
该 Skill 指导开发者在 Web 项目中安装 Contentsquare 跟踪标签,并通过浏览器进行验证。它提供按框架区分的设置步骤,并用向导报告检查标签加载、页面浏览事件和 CSP 问题。
主要功能
- 01按框架提供安装指导
- 02仅在浏览器环境初始化
- 03通过向导进行运行时验证
- 04检查页面浏览事件与 CSP
- 05指导处理验证失败
适用场景
- 01为 Web 应用添加 Contentsquare 跟踪
- 02检查标签加载及导航页面浏览事件
- 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):
tagScriptLoaded: true——标签脚本t.contentsquare.net/uxa/<tagId>.js已加载。initialPageview: true——至少又发出了一次到t.contentsquare.net的请求。cspViolations: []——没有涉及 Contentsquare 域名的 CSP 违规。
不要仅凭“代码看起来没问题”就宣布成功。只有 verify 报告才算数。
开始之前——获取标签 ID
- 在开发者最初的指示中查找标签 ID(例如“安装 Contentsquare,标签 ID 为
81c677ba742d7”)。如果已提供,直接使用——不要再次询问。 - 如果项目中存在
.cs-wizard/state.json,读取其中的tagId并使用。 - 如果仍然没有,请询问:
“你的 Contentsquare 标签 ID 是什么?它是作为
clientId使用的十六进制字符串(例如81c677ba742d7)。你可以在标签代码片段或 Settings 中找到它。”
你需要将此值作为 --tag-id <tagId> 传给 verify。
流程
- 安装——检测框架、安装 SDK 并添加初始化代码。
- 验证——运行一次
npx @contentsquare/wizard verify;由开发者浏览其应用。 - 修复 CSP——仅当
verify报告cspViolations时执行。 - 重新验证——再次运行
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。
如果你使用
_uxaAPI 设置自定义变量或虚拟页面浏览量,请改用 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。
此命令会进行交互,并一直阻塞,直到开发者完成操作。 它会打开真实浏览器并等待。不要认为它卡住了,也不要取消或设置超时时间。 在前台运行,并等待它自行退出。
运行过程:
- 真实浏览器窗口会打开指定 URL,并在页面上方显示 Contentsquare 横幅。
- 告知开发者:“浏览器已打开。请浏览你的应用——等待首个页面加载,点击进入几个应用内路由,并在需要时登录。完成后,点击横幅中的 Done(完成)(或直接关闭窗口)。”
- 只有开发者点击 Done(完成)或关闭窗口后,命令才会结束并打印报告。
从标准输出中打印的 JSON 读取结果,或读取 .cs-wizard/last-report.json(每次运行都会写入)。退出代码:
| 代码 | 含义 |
|---|---|
0 | pass 或 pass-with-recommendation |
1 | fail(报告已运行),或浏览器因未知原因启动失败({"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。这是标签自身对“页面”的定义。
判断方法:
-
没有记录到导航(
navigations为空,或仅有初始load): 开发者没有尝试应用内导航,因此未对此进行测试。请明确说明这一点——不要声称导航跟踪有效或失效。 -
优先关注主框架导航(
top: true)。top: false的条目发生在 iframe 内——可能是应用本身(有些应用运行在 iframe 中),也可能只是第三方嵌入内容(广告、视频、聊天、支付组件)。只有当pageviewBeacons[]中有条目报告了相同的 iframe URL 时,才将top: false导航视为应用导航;否则它们几乎肯定只是嵌入内容,应予以忽略。 -
开发者访问的每个不同页面都应有对应的页面浏览事件。 按意图关联,而非要求字符串完全相同:
- 页面浏览事件报告的
url与导航 URL 匹配(完全匹配,或匹配能标识该应用页面的部分路由信息)→ 该导航已被跟踪。 - 当两边 URL 格式不同,页面浏览事件的
ts紧随导航的ts出现,是有力的佐证。
- 页面浏览事件报告的
-
完整页面(MPA)导航(
type: "load"):每次完整加载都会重新加载标签,并应产生各自的页面浏览事件——预计每次加载大致对应一个事件。 -
SPA / 哈希 / 查询参数导航(
pushState/replaceState/popstate/hashchange,或 URL 仅#…或?…不同):如果开发者在这些页面间切换,但标签没有为这些页面触发新的页面浏览事件,则标签可能未跟踪 URL 更改。请原样给出以下建议:有些应用内导航没有触发页面浏览事件。如果这是单页应用,请在 Contentsquare 应用中启用“Tracking URL Changes”(Project and Users → Tracking URL Changes)。
如果应用纯粹通过哈希或查询字符串进行路由,请指出 Contentsquare 项目中的 URL 更改跟踪可能也需要配置为将它们视为不同的页面。
-
只有在证据表明存在缺漏时才给出建议。如果每个导航到的页面都有匹配的页面浏览事件,则导航跟踪正常——请明确说明。
-
有疑问时,不要猜测——查看代码。 如果关联情况不明确(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。 |