posthog-debugger
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePostHog Debugger
PostHog调试器
Inspect and debug PostHog implementations on any website using browser automation tools. This skill helps developers and product teams understand exactly how PostHog is configured and what data is being captured.
使用浏览器自动化工具检查和调试任意网站上的PostHog实现。此技能可帮助开发人员和产品团队准确了解PostHog的配置方式以及正在捕获的数据。
Critical Rules
核心规则
- Always ask for the URL first if not provided.
- Always ask if the page requires login. If yes, guide the user to log in via Chrome first.
- Use browser tools to navigate and inspect. Prefer Chrome DevTools MCP () or Playwright MCP (
mcp__chrome-devtools__*) tools.mcp__playwright__* - Check multiple signals. PostHog can be implemented in various ways - check scripts, network requests, and the window object.
- Report findings clearly. Summarize what you find in a structured format.
- Never modify anything. This is read-only inspection.
- 若未提供URL,务必先询问。
- 务必询问页面是否需要登录。如果需要,引导用户先通过Chrome登录。
- 使用浏览器工具进行导航和检查。优先使用Chrome DevTools MCP()或Playwright MCP(
mcp__chrome-devtools__*)工具。mcp__playwright__* - 检查多种信号。PostHog的实现方式多种多样——检查脚本、网络请求和window对象。
- 清晰报告发现结果。以结构化格式总结你的发现。
- 绝不修改任何内容。此技能仅用于只读检查。
Initial Flow
初始流程
When a user asks to inspect a PostHog implementation:
- Get the URL (if not provided)
- Navigate to the URL with appended
?__posthog_debug=true - Check if login is required by taking a snapshot and looking for login indicators
- If login required, ask the user to authenticate in the browser
- Once authenticated, proceed with inspection
当用户要求检查PostHog实现时:
- 获取URL(若未提供)
- 导航到附加了的URL
?__posthog_debug=true - 通过截图并查找登录标识来检查是否需要登录
- 若需要登录,请用户在浏览器中完成认证
- 认证完成后,继续进行检查
Detecting Login Pages
检测登录页面
After navigating, take a snapshot and look for login indicators:
- Page title contains "login", "sign in", "authenticate"
- URL contains "login", "signin", "auth", "sso"
- Page has username/password fields
- Page shows "Sign in with Google/GitHub/etc." buttons
导航后,截取页面截图并查找以下登录标识:
- 页面标题包含"login"、"sign in"、"authenticate"
- URL包含"login"、"signin"、"auth"、"sso"
- 页面存在用户名/密码输入框
- 页面显示"Sign in with Google/GitHub/etc."按钮
Authenticated Pages Workflow
已认证页面流程
If you detect a login page or the user mentions the page requires auth:
-
Keep the browser open - you've already navigated there
-
Ask the user to log in:
"This page requires authentication. Please log in using the Chrome browser I just opened. Let me know when you're logged in and on the page you want to inspect." -
Once the user confirms, take a new snapshot to verify they're authenticated
-
Add the debug parameter if not already present and reload if needed
-
Proceed with inspection
若检测到登录页面或用户提及页面需要认证:
-
保持浏览器打开——你已导航到该页面
-
请用户登录:
"该页面需要认证。请使用我刚刚打开的Chrome浏览器登录。登录完成并进入你想要检查的页面后,请告知我。" -
用户确认后,截取新截图以验证已认证
-
若尚未添加调试参数则添加,必要时重新加载页面
-
继续进行检查
Available Browser Tools
可用浏览器工具
Chrome DevTools MCP
Chrome DevTools MCP
- - Navigate to URL
mcp__chrome-devtools__navigate_page - - Get page accessibility tree
mcp__chrome-devtools__take_snapshot - - Run JavaScript to inspect PostHog
mcp__chrome-devtools__evaluate_script - - See network traffic
mcp__chrome-devtools__list_network_requests - - Get request details
mcp__chrome-devtools__get_network_request - - Check for errors
mcp__chrome-devtools__list_console_messages
- - 导航到URL
mcp__chrome-devtools__navigate_page - - 获取页面可访问性树
mcp__chrome-devtools__take_snapshot - - 运行JavaScript检查PostHog
mcp__chrome-devtools__evaluate_script - - 查看网络流量
mcp__chrome-devtools__list_network_requests - - 获取请求详情
mcp__chrome-devtools__get_network_request - - 检查错误信息
mcp__chrome-devtools__list_console_messages
Playwright MCP
Playwright MCP
- - Navigate to URL
mcp__playwright__browser_navigate - - Get page snapshot
mcp__playwright__browser_snapshot - - Run JavaScript
mcp__playwright__browser_evaluate - - See network traffic
mcp__playwright__browser_network_requests - - Check console
mcp__playwright__browser_console_messages
- - 导航到URL
mcp__playwright__browser_navigate - - 获取页面截图
mcp__playwright__browser_snapshot - - 运行JavaScript
mcp__playwright__browser_evaluate - - 查看网络流量
mcp__playwright__browser_network_requests - - 检查控制台
mcp__playwright__browser_console_messages
Inspection Workflow
检查流程
Step 1: Navigate to the Page with Debug Mode
步骤1:导航到开启调试模式的页面
Always add to the URL to enable PostHog's debug mode. This outputs detailed logs to the console.
?__posthog_debug=true- If URL has no query string:
https://example.com?__posthog_debug=true - If URL already has query string:
https://example.com?foo=bar&__posthog_debug=true
Workflow:
- Navigate to the URL with the debug parameter
- Take a snapshot to see what loaded
- Check for login page indicators:
- URL redirected to ,
/login,/signin,/auth/sso - Page title contains "log in", "sign in"
- Page has login form fields
- URL redirected to
- If login detected:
- Tell the user: "I've opened the page but it requires login. Please log in using Chrome, then let me know when you're ready."
- Wait for user confirmation
- Take a new snapshot to verify authentication
- Add debug parameter to the new URL if needed
- If no login needed: Proceed with inspection
**务必在URL中添加**以启用PostHog的调试模式。此模式会在控制台输出详细日志。
?__posthog_debug=true- 若URL无查询字符串:
https://example.com?__posthog_debug=true - 若URL已有查询字符串:
https://example.com?foo=bar&__posthog_debug=true
流程:
- 导航到附加调试参数的URL
- 截取截图查看页面加载情况
- 检查登录页面标识:
- URL重定向到、
/login、/signin、/auth/sso - 页面标题包含"log in"、"sign in"
- 页面存在登录表单输入框
- URL重定向到
- 若检测到登录:
- 告知用户:"我已打开页面,但该页面需要登录。请使用Chrome完成登录,准备好后告知我。"
- 等待用户确认
- 截取新截图验证认证状态
- 必要时为新URL添加调试参数
- 若无需登录:继续检查
Step 2: Check PostHog Global Object
步骤2:检查PostHog全局对象
Execute JavaScript to inspect the object on the window:
posthogjavascript
(() => {
if (typeof posthog === 'undefined') {
return { installed: false };
}
const ph = posthog;
return {
installed: true,
version: ph.version || ph.LIB_VERSION || 'unknown',
config: {
token: ph.config?.token || ph.get_config?.('token') || 'not accessible',
apiHost: ph.config?.api_host || ph.get_config?.('api_host') || 'not accessible',
autocapture: ph.config?.autocapture ?? ph.get_config?.('autocapture') ?? 'not accessible',
capturePageview: ph.config?.capture_pageview ?? ph.get_config?.('capture_pageview') ?? 'not accessible',
capturePageleave: ph.config?.capture_pageleave ?? ph.get_config?.('capture_pageleave') ?? 'not accessible',
sessionRecording: ph.config?.enable_recording_console_log !== undefined ||
ph.sessionRecording?.started ||
'check network',
persistence: ph.config?.persistence || ph.get_config?.('persistence') || 'not accessible',
debug: ph.config?.debug ?? ph.get_config?.('debug') ?? false
},
distinctId: ph.get_distinct_id?.() || 'not accessible',
sessionId: ph.get_session_id?.() || 'not accessible',
featureFlags: ph.getFeatureFlag ? Object.keys(ph.featureFlags?.flags || {}) : [],
activeFeatureFlags: ph.getFeatureFlag ?
Object.entries(ph.featureFlags?.flags || {})
.filter(([_, v]) => v)
.map(([k]) => k) : []
};
})()执行JavaScript检查window上的对象:
posthogjavascript
(() => {
if (typeof posthog === 'undefined') {
return { installed: false };
}
const ph = posthog;
return {
installed: true,
version: ph.version || ph.LIB_VERSION || 'unknown',
config: {
token: ph.config?.token || ph.get_config?.('token') || 'not accessible',
apiHost: ph.config?.api_host || ph.get_config?.('api_host') || 'not accessible',
autocapture: ph.config?.autocapture ?? ph.get_config?.('autocapture') ?? 'not accessible',
capturePageview: ph.config?.capture_pageview ?? ph.get_config?.('capture_pageview') ?? 'not accessible',
capturePageleave: ph.config?.capture_pageleave ?? ph.get_config?.('capture_pageleave') ?? 'not accessible',
sessionRecording: ph.config?.enable_recording_console_log !== undefined ||
ph.sessionRecording?.started ||
'check network',
persistence: ph.config?.persistence || ph.get_config?.('persistence') || 'not accessible',
debug: ph.config?.debug ?? ph.get_config?.('debug') ?? false
},
distinctId: ph.get_distinct_id?.() || 'not accessible',
sessionId: ph.get_session_id?.() || 'not accessible',
featureFlags: ph.getFeatureFlag ? Object.keys(ph.featureFlags?.flags || {}) : [],
activeFeatureFlags: ph.getFeatureFlag ?
Object.entries(ph.featureFlags?.flags || {})
.filter(([_, v]) => v)
.map(([k]) => k) : []
};
})()Step 2b: Check for Bundled PostHog (Remote Config)
步骤2b:检查捆绑式PostHog(远程配置)
If is not on , check for bundled implementations that use :
posthogwindow_POSTHOG_REMOTE_CONFIGjavascript
(() => {
const remoteConfig = window._POSTHOG_REMOTE_CONFIG;
if (!remoteConfig) {
return { found: false };
}
const tokens = Object.keys(remoteConfig);
const configs = tokens.map(token => {
const cfg = remoteConfig[token]?.config || {};
return {
token,
hasFeatureFlags: cfg.hasFeatureFlags || false,
autocapture: !cfg.autocapture_opt_out,
sessionRecording: cfg.sessionRecording || false,
heatmaps: cfg.heatmaps || false,
surveys: cfg.surveys || false,
capturePerformance: cfg.capturePerformance || {},
defaultIdentifiedOnly: cfg.defaultIdentifiedOnly || false
};
});
return {
found: true,
bundled: true,
configs
};
})()若不在上,检查使用的捆绑式实现:
posthogwindow_POSTHOG_REMOTE_CONFIGjavascript
(() => {
const remoteConfig = window._POSTHOG_REMOTE_CONFIG;
if (!remoteConfig) {
return { found: false };
}
const tokens = Object.keys(remoteConfig);
const configs = tokens.map(token => {
const cfg = remoteConfig[token]?.config || {};
return {
token,
hasFeatureFlags: cfg.hasFeatureFlags || false,
autocapture: !cfg.autocapture_opt_out,
sessionRecording: cfg.sessionRecording || false,
heatmaps: cfg.heatmaps || false,
surveys: cfg.surveys || false,
capturePerformance: cfg.capturePerformance || {},
defaultIdentifiedOnly: cfg.defaultIdentifiedOnly || false
};
});
return {
found: true,
bundled: true,
configs
};
})()Step 2c: Check Console for PostHog Debug Messages
步骤2c:检查控制台中的PostHog调试消息
With , PostHog outputs detailed logs. Use and look for entries:
?__posthog_debug=truelist_console_messages[PostHog.js]Key messages to look for:
- - Shows persistence type (localStorage, sessionStorage, cookie)
[PostHog.js] Persistence loaded - - Surveys module loaded
[PostHog.js] [Surveys] Surveys loaded successfully - - Whether surveys are enabled
[PostHog.js] [Surveys] flags response received, isSurveysEnabled: X - - Session recording status
[PostHog.js] [SessionRecording] - - Web experiments/feature flags
[PostHog.js] [WebExperiments] - - Configuration changes
[PostHog.js] set_config
Important distinction:
- Module loaded = The JavaScript file loaded successfully
- Feature enabled = The feature is turned on in PostHog settings
A module can load but still be disabled. For example:
[PostHog.js] [Surveys] Surveys loaded successfully <- Module loaded
[PostHog.js] [Surveys] flags response received, isSurveysEnabled: false <- Feature disabled开启后,PostHog会输出详细日志。使用查找条目:
?__posthog_debug=truelist_console_messages[PostHog.js]需重点关注的消息:
- - 显示持久化类型(localStorage、sessionStorage、cookie)
[PostHog.js] Persistence loaded - - 调查模块已加载
[PostHog.js] [Surveys] Surveys loaded successfully - - 调查功能是否启用
[PostHog.js] [Surveys] flags response received, isSurveysEnabled: X - - 会话录制状态
[PostHog.js] [SessionRecording] - - Web实验/功能标志
[PostHog.js] [WebExperiments] - - 配置变更
[PostHog.js] set_config
重要区别:
- 模块已加载 = JavaScript文件加载成功
- 功能已启用 = 该功能在PostHog设置中已开启
模块可能已加载但仍处于禁用状态。例如:
[PostHog.js] [Surveys] Surveys loaded successfully <- 模块已加载
[PostHog.js] [Surveys] flags response received, isSurveysEnabled: false <- 功能已禁用Step 3: Check for PostHog Script
步骤3:检查PostHog脚本
Look for PostHog scripts in the page:
javascript
(() => {
const scripts = Array.from(document.querySelectorAll('script'));
const posthogScripts = scripts.filter(s =>
(s.src && (s.src.includes('posthog') || s.src.includes('ph.js'))) ||
(s.textContent && (s.textContent.includes('posthog.init') || s.textContent.includes('!function(t,e)')))
);
return {
found: posthogScripts.length > 0,
scripts: posthogScripts.map(s => ({
src: s.src || 'inline',
async: s.async,
defer: s.defer,
type: s.type || 'text/javascript'
}))
};
})()在页面中查找PostHog脚本:
javascript
(() => {
const scripts = Array.from(document.querySelectorAll('script'));
const posthogScripts = scripts.filter(s =>
(s.src && (s.src.includes('posthog') || s.src.includes('ph.js'))) ||
(s.textContent && (s.textContent.includes('posthog.init') || s.textContent.includes('!function(t,e)')))
);
return {
found: posthogScripts.length > 0,
scripts: posthogScripts.map(s => ({
src: s.src || 'inline',
async: s.async,
defer: s.defer,
type: s.type || 'text/javascript'
}))
};
})()Step 4: Check Network Requests
步骤4:检查网络请求
Filter network requests to find PostHog traffic. PostHog may use:
Standard domains:
*.posthog.com- /
us.i.posthog.comeu.i.posthog.com - /
us-assets.i.posthog.comeu-assets.i.posthog.com
Custom proxy domains (common patterns):
ph.yourcompany.comanalytics.yourcompany.comt.yourcompany.com- Any domain with in the path (PostHog config)
/array/phc_
Endpoints to look for:
- or
/e/- Events/capture/ - - Session recording
/s/ - or
/decide/- Feature flags/flags/ - - Batched events
/batch/ - - Remote config (bundled implementations)
/array/phc_*/config.js - - Surveys module
/static/surveys.js - - Session recording module
/static/recorder.js
How to identify a custom proxy:
- Look for requests with PostHog-specific paths (,
/flags/)/array/phc_ - Check network request details for PostHog headers
- Look for tokens in request URLs or bodies
phc_
筛选网络请求以查找PostHog流量。PostHog可能使用:
标准域名:
*.posthog.com- /
us.i.posthog.comeu.i.posthog.com - /
us-assets.i.posthog.comeu-assets.i.posthog.com
自定义代理域名(常见模式):
ph.yourcompany.comanalytics.yourcompany.comt.yourcompany.com- 路径中包含的任意域名(PostHog配置)
/array/phc_
需查找的端点:
- 或
/e/- 事件/capture/ - - 会话录制
/s/ - 或
/decide/- 功能标志/flags/ - - 批量事件
/batch/ - - 远程配置(捆绑式实现)
/array/phc_*/config.js - - 调查模块
/static/surveys.js - - 会话录制模块
/static/recorder.js
如何识别自定义代理:
- 查找带有PostHog特定路径(、
/flags/)的请求/array/phc_ - 检查网络请求详情中的PostHog头部
- 在请求URL或主体中查找令牌
phc_
Step 5: Check for Common Issues
步骤5:检查常见问题
Run diagnostics:
javascript
(() => {
const issues = [];
// Check if posthog exists
if (typeof posthog === 'undefined') {
issues.push('PostHog not found on window object');
return { issues };
}
// Check for multiple instances
if (window.__POSTHOG_INSTANCES__ && window.__POSTHOG_INSTANCES__.length > 1) {
issues.push('Multiple PostHog instances detected - may cause duplicate events');
}
// Check if initialized
if (!posthog.get_distinct_id || !posthog.get_distinct_id()) {
issues.push('PostHog may not be fully initialized');
}
// Check consent mode
if (posthog.has_opted_out_capturing && posthog.has_opted_out_capturing()) {
issues.push('User has opted out of tracking');
}
// Check for debug mode in production
const isDebug = posthog.config?.debug || posthog.get_config?.('debug');
const hostname = window.location.hostname;
if (isDebug && !hostname.includes('localhost') && !hostname.includes('127.0.0.1')) {
issues.push('Debug mode is enabled in production');
}
// Check autocapture
const autocapture = posthog.config?.autocapture ?? posthog.get_config?.('autocapture');
if (autocapture === false) {
issues.push('Autocapture is disabled - only manual events will be tracked');
}
return {
issues: issues.length > 0 ? issues : ['No issues detected'],
checksRun: true
};
})()运行诊断:
javascript
(() => {
const issues = [];
// 检查posthog是否存在
if (typeof posthog === 'undefined') {
issues.push('PostHog未在window对象中找到');
return { issues };
}
// 检查是否存在多个实例
if (window.__POSTHOG_INSTANCES__ && window.__POSTHOG_INSTANCES__.length > 1) {
issues.push('检测到多个PostHog实例 - 可能导致重复事件');
}
// 检查是否已初始化
if (!posthog.get_distinct_id || !posthog.get_distinct_id()) {
issues.push('PostHog可能未完全初始化');
}
// 检查同意模式
if (posthog.has_opted_out_capturing && posthog.has_opted_out_capturing()) {
issues.push('用户已选择退出追踪');
}
// 检查生产环境中是否启用调试模式
const isDebug = posthog.config?.debug || posthog.get_config?.('debug');
const hostname = window.location.hostname;
if (isDebug && !hostname.includes('localhost') && !hostname.includes('127.0.0.1')) {
issues.push('生产环境中启用了调试模式');
}
// 检查自动捕获
const autocapture = posthog.config?.autocapture ?? posthog.get_config?.('autocapture');
if (autocapture === false) {
issues.push('自动捕获已禁用 - 仅会追踪手动事件');
}
return {
issues: issues.length > 0 ? issues : ['未检测到问题'],
checksRun: true
};
})()Step 6: Capture Recent Events (if debug available)
步骤6:捕获最近事件(若调试可用)
If debug mode is on or we can access the queue:
javascript
(() => {
if (typeof posthog === 'undefined') return { events: [] };
// Try to get queued events
const queue = posthog._requestQueue?.queue ||
posthog.requestQueue?.queue ||
[];
// Get recent events from persistence if available
const stored = posthog.persistence?.props?.$stored_events || [];
return {
queuedEvents: queue.length,
recentEventTypes: [...new Set([...queue, ...stored].map(e => e?.event || 'unknown').slice(0, 20))]
};
})()若调试模式已开启或可访问队列:
javascript
(() => {
if (typeof posthog === 'undefined') return { events: [] };
// 尝试获取队列中的事件
const queue = posthog._requestQueue?.queue ||
posthog.requestQueue?.queue ||
[];
// 从持久化存储中获取最近事件(若可用)
const stored = posthog.persistence?.props?.$stored_events || [];
return {
queuedEvents: queue.length,
recentEventTypes: [...new Set([...queue, ...stored].map(e => e?.event || 'unknown').slice(0, 20))]
};
})()Step 7: Detect Other Analytics Tools
步骤7:检测其他分析工具
Scan network requests and scripts to identify all analytics/tracking tools on the page. Use known patterns for named tools, and detect unknown tracking scripts as a fallback.
javascript
(() => {
const scripts = Array.from(document.querySelectorAll('script[src]')).map(s => s.src);
const hostname = window.location.hostname.replace('www.', '');
const knownTools = [];
const matchedScripts = new Set();
const patterns = {
'Google Analytics': /google-analytics\.com|gtag\/js/i,
'Google Tag Manager': /googletagmanager\.com\/gtm/i,
'Facebook Pixel': /connect\.facebook\.net.*fbevents/i,
'LinkedIn Insight': /snap\.licdn\.com/i,
'HubSpot': /js\.hs-scripts\.com|js\.hsforms\.com/i,
'Hotjar': /static\.hotjar\.com/i,
'Segment': /cdn\.segment\.com/i,
'Mixpanel': /cdn\.mxpnl\.com|mixpanel\.com/i,
'Amplitude': /cdn\.amplitude\.com/i,
'Heap': /heap-analytics\.com|heapanalytics\.com/i,
'Intercom': /widget\.intercom\.io|intercomcdn\.com/i,
'Drift': /js\.driftt\.com/i,
'Zendesk': /static\.zdassets\.com/i,
'Crisp': /client\.crisp\.chat/i,
'FullStory': /fullstory\.com\/s\/fs\.js/i,
'LogRocket': /cdn\.logrocket\.com/i,
'Sentry': /browser\.sentry-cdn\.com/i,
'Datadog': /datadoghq\.com/i,
'Snowplow': /cdn\.snowplow/i,
'Rudderstack': /cdn\.rudderlabs\.com/i,
'Clearbit': /tag\.clearbitscripts\.com/i,
'Dreamdata': /cdn\.dreamdata\.cloud/i,
'GrowthBook': /cdn\.growthbook\.io/i,
'LaunchDarkly': /sdk\.launchdarkly\.com/i,
'Optimizely': /cdn\.optimizely\.com/i,
'VWO': /dev\.visualwebsiteoptimizer\.com/i,
'Ahrefs': /analytics\.ahrefs\.com/i,
'AdRoll': /s\.adroll\.com/i,
'Factors.ai': /app\.factors\.ai/i,
'Vector': /cdn\.vector\.co/i,
'Leadfeeder': /sc\.lfeeder\.com/i,
'Pendo': /cdn\.pendo\.io/i,
'Chameleon': /fast\.chameleon\.io/i,
'Appcues': /fast\.appcues\.com/i,
'UserPilot': /js\.userpilot\.io/i,
'Mouseflow': /cdn\.mouseflow\.com/i,
'Lucky Orange': /tools\.luckyorange\.com/i,
'Crazy Egg': /script\.crazyegg\.com/i,
'Plausible': /plausible\.io\/js/i,
'Fathom': /cdn\.usefathom\.com/i,
'Simple Analytics': /scripts\.simpleanalyticscdn\.com/i,
'Matomo': /matomo\.js|piwik\.js/i,
'Klaviyo': /static\.klaviyo\.com/i,
'Customer.io': /track\.customer\.io/i,
'Braze': /sdk\.iad-\d+\.braze\.com/i,
'OneSignal': /cdn\.onesignal\.com/i,
'Insider': /insr\.io/i,
'Mutiny': /cdn\.mutinycdn\.com/i,
'Qualified': /js\.qualified\.com/i,
'Chilipiper': /js\.chilipiper\.com/i,
'Typekit': /use\.typekit\.net/i,
'Google Fonts': /fonts\.googleapis\.com/i,
'Cookiebot': /consent\.cookiebot\.com/i,
'OneTrust': /cdn\.cookielaw\.org/i,
'TrustArc': /consent\.trustarc\.com/i,
'Osano': /cmp\.osano\.com/i,
'Usercentrics': /app\.usercentrics\.eu/i,
'OpenLI/Legal Monster': /widgets\.legalmonster\.com|openli\.com/i,
'Nelio A/B Testing': /nelio-ab-testing/i,
'Mesh': /mesh-interactive|withmesh\.com/i,
'Reddit Pixel': /redditstatic\.com|rdt\.li/i,
'Webflow': /wdfl\.co|webflow\.com\/js/i,
'Dub.co': /dubcdn\.com|dub\.co/i
};
// Match known tools
for (const [name, pattern] of Object.entries(patterns)) {
for (const src of scripts) {
if (pattern.test(src)) {
knownTools.push(name);
matchedScripts.add(src);
break;
}
}
}
// Find unknown tracking scripts
const trackingKeywords = /track|analytics|pixel|tag|beacon|collect|measure|metric|event|telemetry|monitor/i;
const unknownScripts = scripts.filter(src => {
if (matchedScripts.has(src)) return false;
try {
const url = new URL(src);
const scriptHost = url.hostname.replace('www.', '');
// Skip same-domain scripts
if (scriptHost === hostname || scriptHost.endsWith('.' + hostname)) return false;
// Skip common CDNs that host non-tracking code
if (/unpkg\.com|jsdelivr\.net|cdnjs\.cloudflare\.com|ajax\.googleapis\.com/i.test(scriptHost)) return false;
// Include if it has tracking-like keywords or is from a third-party
return trackingKeywords.test(src) || true;
} catch {
return false;
}
});
// Extract just the domain from unknown scripts for cleaner output
const unknownDomains = [...new Set(unknownScripts.map(src => {
try {
return new URL(src).hostname;
} catch {
return src;
}
}))].sort();
return {
knownTools: [...new Set(knownTools)].sort(),
unknownScripts: unknownDomains
};
})()扫描网络请求和脚本以识别页面上的所有分析/追踪工具。使用已知工具的模式进行匹配,将未匹配的追踪脚本作为回退检测为未知工具。
javascript
(() => {
const scripts = Array.from(document.querySelectorAll('script[src]')).map(s => s.src);
const hostname = window.location.hostname.replace('www.', '');
const knownTools = [];
const matchedScripts = new Set();
const patterns = {
'Google Analytics': /google-analytics\.com|gtag\/js/i,
'Google Tag Manager': /googletagmanager\.com\/gtm/i,
'Facebook Pixel': /connect\.facebook\.net.*fbevents/i,
'LinkedIn Insight': /snap\.licdn\.com/i,
'HubSpot': /js\.hs-scripts\.com|js\.hsforms\.com/i,
'Hotjar': /static\.hotjar\.com/i,
'Segment': /cdn\.segment\.com/i,
'Mixpanel': /cdn\.mxpnl\.com|mixpanel\.com/i,
'Amplitude': /cdn\.amplitude\.com/i,
'Heap': /heap-analytics\.com|heapanalytics\.com/i,
'Intercom': /widget\.intercom\.io|intercomcdn\.com/i,
'Drift': /js\.driftt\.com/i,
'Zendesk': /static\.zdassets\.com/i,
'Crisp': /client\.crisp\.chat/i,
'FullStory': /fullstory\.com\/s\/fs\.js/i,
'LogRocket': /cdn\.logrocket\.com/i,
'Sentry': /browser\.sentry-cdn\.com/i,
'Datadog': /datadoghq\.com/i,
'Snowplow': /cdn\.snowplow/i,
'Rudderstack': /cdn\.rudderlabs\.com/i,
'Clearbit': /tag\.clearbitscripts\.com/i,
'Dreamdata': /cdn\.dreamdata\.cloud/i,
'GrowthBook': /cdn\.growthbook\.io/i,
'LaunchDarkly': /sdk\.launchdarkly\.com/i,
'Optimizely': /cdn\.optimizely\.com/i,
'VWO': /dev\.visualwebsiteoptimizer\.com/i,
'Ahrefs': /analytics\.ahrefs\.com/i,
'AdRoll': /s\.adroll\.com/i,
'Factors.ai': /app\.factors\.ai/i,
'Vector': /cdn\.vector\.co/i,
'Leadfeeder': /sc\.lfeeder\.com/i,
'Pendo': /cdn\.pendo\.io/i,
'Chameleon': /fast\.chameleon\.io/i,
'Appcues': /fast\.appcues\.com/i,
'UserPilot': /js\.userpilot\.io/i,
'Mouseflow': /cdn\.mouseflow\.com/i,
'Lucky Orange': /tools\.luckyorange\.com/i,
'Crazy Egg': /script\.crazyegg\.com/i,
'Plausible': /plausible\.io\/js/i,
'Fathom': /cdn\.usefathom\.com/i,
'Simple Analytics': /scripts\.simpleanalyticscdn\.com/i,
'Matomo': /matomo\.js|piwik\.js/i,
'Klaviyo': /static\.klaviyo\.com/i,
'Customer.io': /track\.customer\.io/i,
'Braze': /sdk\.iad-\d+\.braze\.com/i,
'OneSignal': /cdn\.onesignal\.com/i,
'Insider': /insr\.io/i,
'Mutiny': /cdn\.mutinycdn\.com/i,
'Qualified': /js\.qualified\.com/i,
'Chilipiper': /js\.chilipiper\.com/i,
'Typekit': /use\.typekit\.net/i,
'Google Fonts': /fonts\.googleapis\.com/i,
'Cookiebot': /consent\.cookiebot\.com/i,
'OneTrust': /cdn\.cookielaw\.org/i,
'TrustArc': /consent\.trustarc\.com/i,
'Osano': /cmp\.osano\.com/i,
'Usercentrics': /app\.usercentrics\.eu/i,
'OpenLI/Legal Monster': /widgets\.legalmonster\.com|openli\.com/i,
'Nelio A/B Testing': /nelio-ab-testing/i,
'Mesh': /mesh-interactive|withmesh\.com/i,
'Reddit Pixel': /redditstatic\.com|rdt\.li/i,
'Webflow': /wdfl\.co|webflow\.com\/js/i,
'Dub.co': /dubcdn\.com|dub\.co/i
};
// 匹配已知工具
for (const [name, pattern] of Object.entries(patterns)) {
for (const src of scripts) {
if (pattern.test(src)) {
knownTools.push(name);
matchedScripts.add(src);
break;
}
}
}
// 查找未知追踪脚本
const trackingKeywords = /track|analytics|pixel|tag|beacon|collect|measure|metric|event|telemetry|monitor/i;
const unknownScripts = scripts.filter(src => {
if (matchedScripts.has(src)) return false;
try {
const url = new URL(src);
const scriptHost = url.hostname.replace('www.', '');
// 跳过同域脚本
if (scriptHost === hostname || scriptHost.endsWith('.' + hostname)) return false;
// 跳过托管非追踪代码的常见CDN
if (/unpkg\.com|jsdelivr\.net|cdnjs\.cloudflare\.com|ajax\.googleapis\.com/i.test(scriptHost)) return false;
// 若包含类追踪关键词或来自第三方则纳入
return trackingKeywords.test(src) || true;
} catch {
return false;
}
});
// 从未知脚本中提取域名以简化输出
const unknownDomains = [...new Set(unknownScripts.map(src => {
try {
return new URL(src).hostname;
} catch {
return src;
}
}))].sort();
return {
knownTools: [...new Set(knownTools)].sort(),
unknownScripts: unknownDomains
};
})()Response Format
响应格式
After inspection, provide a structured summary. Be factual and concise - no commentary or recommendations unless asked. Use emojis to indicate status at a glance.
Status emojis:
- ✅ = Yes / Enabled / Active / Installed
- ❌ = No / Disabled / Not found
- ⚠️ = Warning / Issue detected
undefined检查完成后,提供结构化总结。内容需真实简洁——除非被询问,否则不添加评论或建议。使用表情符号快速指示状态。
状态表情符号:
- ✅ = 是/已启用/活跃/已安装
- ❌ = 否/已禁用/未找到
- ⚠️ = 警告/检测到问题
undefinedPostHog Implementation Summary
PostHog实现总结
Status
状态
✅ Installed / ✅ Installed (bundled) / ❌ Not Found
✅ 已安装 / ✅ 已安装(捆绑式) / ❌ 未找到
Implementation Type
实现类型
[Global window.posthog / Bundled (not exposed globally) / Custom proxy]
[全局window.posthog / 捆绑式(未全局暴露) / 自定义代理]
Configuration
配置
- Version: [version]
- API Host: [host] ([US/EU Cloud] / [Custom proxy] / [Self-hosted])
- Project Token: [full token]
- Persistence: [localStorage/sessionStorage/cookie/memory]
- 版本: [version]
- API主机: [host] ([美国/欧盟云] / [自定义代理] / [自托管])
- 项目令牌: [完整令牌]
- 持久化: [localStorage/sessionStorage/cookie/memory]
Features (Module Loaded → Feature Enabled)
功能(模块已加载 → 功能已启用)
| Feature | Module Loaded | Enabled |
|---|---|---|
| Autocapture | ✅ / ❌ | ✅ / ❌ |
| Session Recording | ✅ / ❌ | ✅ / ❌ |
| Surveys | ✅ / ❌ | ✅ / ❌ |
| Heatmaps | ✅ / ❌ | ✅ / ❌ |
| Feature Flags | ✅ / ❌ | ✅ / ❌ |
| Web Vitals | ✅ / ❌ | ✅ / ❌ |
| 功能 | 模块已加载 | 已启用 |
|---|---|---|
| 自动捕获 | ✅ / ❌ | ✅ / ❌ |
| 会话录制 | ✅ / ❌ | ✅ / ❌ |
| 调查 | ✅ / ❌ | ✅ / ❌ |
| 热力图 | ✅ / ❌ | ✅ / ❌ |
| 功能标志 | ✅ / ❌ | ✅ / ❌ |
| Web性能指标 | ✅ / ❌ | ✅ / ❌ |
Identifiers
标识符
- Distinct ID: [id]
- Session ID: [id]
- Distinct ID: [id]
- Session ID: [id]
Feature Flags
功能标志
[List of active flags or "None loaded"]
[活跃标志列表或"未加载任何标志"]
Network Activity
网络活动
- Events endpoint: ✅ / ❌
- Session recording: ✅ / ❌
- Decide/flags endpoint: ✅ / ❌
- Surveys endpoint: ✅ / ❌
- 事件端点:✅ / ❌
- 会话录制:✅ / ❌
- Decide/flags端点:✅ / ❌
- 调查端点:✅ / ❌
Issues Found
检测到的问题
✅ None detected
— or —
⚠️ [Issue description]
✅ 未检测到问题
— 或 —
⚠️ [问题描述]
Script Loading
脚本加载
- Source: [CDN/Self-hosted/NPM bundle/Custom proxy]
- Loading: [Async/Sync/Defer]
- 来源: [CDN/自托管/NPM包/自定义代理]
- 加载方式: [异步/同步/延迟]
Other Analytics Tools Detected
检测到的其他分析工具
[List of recognized analytics, tracking, and marketing tools]
[已识别的分析、追踪和营销工具列表]
Other External Scripts
其他外部脚本
[Third-party script domains not matched to known tools]
undefined[未匹配到已知工具的第三方脚本域名]
undefinedCommon Questions and How to Answer Them
常见问题及回答方式
"How is PostHog implemented on this page?"
"PostHog在该页面上是如何实现的?"
Run full inspection workflow and provide complete summary.
运行完整检查流程并提供完整总结。
"Is PostHog tracking working?"
"PostHog追踪是否正常工作?"
- Check if posthog object exists
- Verify network requests are being sent
- Check for any errors in console
- Look for opted-out status
- 检查posthog对象是否存在
- 验证是否正在发送网络请求
- 检查控制台中的错误信息
- 查看用户是否选择退出追踪
"What events are being tracked?"
"正在追踪哪些事件?"
- Check autocapture status
- Look at network requests to or
/e//capture/ - Try to access event queue
- Note if $pageview, $pageleave, etc. are enabled
- 检查自动捕获状态
- 查看发送到或
/e/的网络请求/capture/ - 尝试访问事件队列
- 记录$pageview、$pageleave等是否已启用
"Is session recording enabled?"
"会话录制是否已启用?"
- Check config for recording settings
- Look for network requests
/s/ - Check sessionRecording object state
- 检查配置中的录制设置
- 查找网络请求
/s/ - 检查sessionRecording对象状态
"What feature flags are active?"
"哪些功能标志处于活跃状态?"
- Check featureFlags object on posthog
- Look for network request
/decide/ - List all flags and their values
- 检查posthog上的featureFlags对象
- 查找网络请求
/decide/ - 列出所有标志及其值
"Are there any issues with the implementation?"
"实现中存在哪些问题?"
Run the diagnostic checks and report findings.
运行诊断检查并报告发现结果。
"Is this using the EU or US cloud?"
"这使用的是欧盟还是美国云?"
Check the api_host configuration:
- = US Cloud
us.i.posthog.com - = EU Cloud
eu.i.posthog.com - = Legacy (defaults to US)
app.posthog.com - Custom domain = Self-hosted or proxy
检查api_host配置:
- = 美国云
us.i.posthog.com - = 欧盟云
eu.i.posthog.com - = 旧版(默认美国)
app.posthog.com - 自定义域名 = 自托管或代理
Example Conversation
对话示例
User: "How is PostHog implemented on https://example.com?"
Claude: "I'll navigate to example.com with debug mode enabled and inspect the PostHog implementation."
[Navigates to https://example.com?__posthog_debug=true]
[Runs JavaScript checks]
[Checks console for PostHog debug messages]
[Analyzes network requests]
Claude:
undefined用户: "PostHog在https://example.com上是如何实现的?"
Claude: "我将开启调试模式导航到example.com并检查PostHog实现。"
[导航到https://example.com?__posthog_debug=true]
[运行JavaScript检查]
[检查控制台中的PostHog调试消息]
[分析网络请求]
Claude:
undefinedPostHog Implementation Summary
PostHog实现总结
Status
状态
✅ Installed
✅ 已安装
Implementation Type
实现类型
Global window.posthog
全局window.posthog
Configuration
配置
- Version: 1.96.1
- API Host: https://us.i.posthog.com (US Cloud)
- Project Token: phc_abc123def456ghi789jkl012mno345
- Persistence: localStorage+cookie
- 版本: 1.96.1
- API主机: https://us.i.posthog.com(美国云)
- 项目令牌: phc_abc123def456ghi789jkl012mno345
- 持久化: localStorage+cookie
Features (Module Loaded → Feature Enabled)
功能(模块已加载 → 功能已启用)
| Feature | Module Loaded | Enabled |
|---|---|---|
| Autocapture | ✅ | ✅ |
| Session Recording | ✅ | ✅ |
| Surveys | ✅ | ❌ |
| Heatmaps | ❌ | ❌ |
| Feature Flags | ✅ | ✅ |
| Web Vitals | ✅ | ✅ |
| 功能 | 模块已加载 | 已启用 |
|---|---|---|
| 自动捕获 | ✅ | ✅ |
| 会话录制 | ✅ | ✅ |
| 调查 | ✅ | ❌ |
| 热力图 | ❌ | ❌ |
| 功能标志 | ✅ | ✅ |
| Web性能指标 | ✅ | ✅ |
Identifiers
标识符
- Distinct ID: 018d4f2a-1234-7abc-def0-123456789abc
- Session ID: 018d4f2a-5678-7xyz-abc0-987654321xyz
- Distinct ID: 018d4f2a-1234-7abc-def0-123456789abc
- Session ID: 018d4f2a-5678-7xyz-abc0-987654321xyz
Feature Flags
功能标志
- ✅
new-checkout-flow - ❌
beta-features
- ✅
new-checkout-flow - ❌
beta-features
Network Activity
网络活动
- Events endpoint: ✅
- Session recording: ✅
- Decide/flags endpoint: ✅
- Surveys endpoint: ✅
- 事件端点:✅
- 会话录制:✅
- Decide/flags端点:✅
- 调查端点:✅
Issues Found
检测到的问题
✅ None detected
✅ 未检测到问题
Script Loading
脚本加载
- Source: CDN (us-assets.i.posthog.com)
- Loading: Async
- 来源: CDN(us-assets.i.posthog.com)
- 加载方式: 异步
Other Analytics Tools Detected
检测到的其他分析工具
- Google Tag Manager
- Google Analytics
- HubSpot
- Google Tag Manager
- Google Analytics
- HubSpot
Other External Scripts
其他外部脚本
- cdn.example-vendor.com
---
**Example 2: Authenticated page with custom proxy**
**User:** "Check PostHog on https://app.example.com/dashboard"
**Claude:** "I'll navigate to that page with debug mode enabled."
[Navigates to https://app.example.com/dashboard?__posthog_debug=true]
[Takes snapshot, sees login page]
**Claude:** "I've opened the page but it requires login. Please log in using the Chrome browser I just opened. Let me know when you're on the dashboard."
**User:** "I'm logged in"
**Claude:** [Takes new snapshot, verifies authenticated, runs inspection]
- cdn.example-vendor.com
---
**示例2:带自定义代理的已认证页面**
**用户:** "检查https://app.example.com/dashboard上的PostHog"
**Claude:** "我将开启调试模式导航到该页面。"
[导航到https://app.example.com/dashboard?__posthog_debug=true]
[截取截图,发现登录页面]
**Claude:** "我已打开页面,但该页面需要登录。请使用我刚刚打开的Chrome浏览器登录。进入仪表板后请告知我。"
**用户:** "我已登录"
**Claude:** [截取新截图,验证已认证,运行检查]
PostHog Implementation Summary
PostHog实现总结
Status
状态
✅ Installed (bundled)
✅ 已安装(捆绑式)
Implementation Type
实现类型
Bundled (not exposed globally) via custom proxy
捆绑式(未全局暴露)通过自定义代理
Configuration
配置
- Version: 1.257.2
- API Host: ph.example.com (Custom proxy)
- Project Token: phc_abc123def456ghi789jkl012mno345
- Persistence: sessionStorage
- 版本: 1.257.2
- API主机: ph.example.com(自定义代理)
- 项目令牌: phc_abc123def456ghi789jkl012mno345
- 持久化: sessionStorage
Features (Module Loaded → Feature Enabled)
功能(模块已加载 → 功能已启用)
| Feature | Module Loaded | Enabled |
|---|---|---|
| Autocapture | ✅ | ❌ |
| Session Recording | ❌ | ❌ |
| Surveys | ✅ | ❌ |
| Heatmaps | ❌ | ❌ |
| Feature Flags | ✅ | ✅ |
| Web Vitals | ✅ | ❌ |
| 功能 | 模块已加载 | 已启用 |
|---|---|---|
| 自动捕获 | ✅ | ❌ |
| 会话录制 | ❌ | ❌ |
| 调查 | ✅ | ❌ |
| 热力图 | ❌ | ❌ |
| 功能标志 | ✅ | ✅ |
| Web性能指标 | ✅ | ❌ |
Identifiers
标识符
- Distinct ID: (not accessible - bundled)
- Session ID: (not accessible - bundled)
- Distinct ID: (无法访问 - 捆绑式)
- Session ID: (无法访问 - 捆绑式)
Network Activity
网络活动
- Events endpoint: ✅
- Session recording: ❌
- Decide/flags endpoint: ✅
- Surveys endpoint: ✅ (module loaded, feature disabled)
- 事件端点:✅
- 会话录制:❌
- Decide/flags端点:✅
- 调查端点:✅(模块已加载,功能已禁用)
Issues Found
检测到的问题
✅ None detected
✅ 未检测到问题
Script Loading
脚本加载
- Source: Custom proxy (ph.example.com)
- Loading: Bundled in app
undefined- 来源: 自定义代理(ph.example.com)
- 加载方式: 捆绑到应用中
undefined