Loading...
Loading...
Debug and inspect PostHog implementations on any website. Use this skill when a user wants to understand how PostHog is implemented on a page, troubleshoot tracking issues, verify configuration, check what events are being sent, or audit a PostHog setup. Works with Chrome DevTools MCP and Playwright MCP to inspect live websites.
npx skill4agent add posthog/skills posthog-debuggermcp__chrome-devtools__*mcp__playwright__*?__posthog_debug=true"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."mcp__chrome-devtools__navigate_pagemcp__chrome-devtools__take_snapshotmcp__chrome-devtools__evaluate_scriptmcp__chrome-devtools__list_network_requestsmcp__chrome-devtools__get_network_requestmcp__chrome-devtools__list_console_messagesmcp__playwright__browser_navigatemcp__playwright__browser_snapshotmcp__playwright__browser_evaluatemcp__playwright__browser_network_requestsmcp__playwright__browser_console_messages?__posthog_debug=truehttps://example.com?__posthog_debug=truehttps://example.com?foo=bar&__posthog_debug=true/login/signin/auth/ssoposthog(() => {
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) : []
};
})()posthogwindow_POSTHOG_REMOTE_CONFIG(() => {
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
};
})()?__posthog_debug=truelist_console_messages[PostHog.js][PostHog.js] Persistence loaded[PostHog.js] [Surveys] Surveys loaded successfully[PostHog.js] [Surveys] flags response received, isSurveysEnabled: X[PostHog.js] [SessionRecording][PostHog.js] [WebExperiments][PostHog.js] set_config[PostHog.js] [Surveys] Surveys loaded successfully <- Module loaded
[PostHog.js] [Surveys] flags response received, isSurveysEnabled: false <- Feature disabled(() => {
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.comus.i.posthog.comeu.i.posthog.comus-assets.i.posthog.comeu-assets.i.posthog.comph.yourcompany.comanalytics.yourcompany.comt.yourcompany.com/array/phc_/e//capture//s//decide//flags//batch//array/phc_*/config.js/static/surveys.js/static/recorder.js/flags//array/phc_phc_(() => {
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
};
})()(() => {
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))]
};
})()(() => {
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
};
})()## PostHog Implementation Summary
### Status
✅ Installed / ✅ Installed (bundled) / ❌ Not Found
### Implementation Type
[Global window.posthog / Bundled (not exposed globally) / Custom proxy]
### Configuration
- **Version:** [version]
- **API Host:** [host] ([US/EU Cloud] / [Custom proxy] / [Self-hosted])
- **Project Token:** [full token]
- **Persistence:** [localStorage/sessionStorage/cookie/memory]
### Features (Module Loaded → Feature Enabled)
| Feature | Module Loaded | Enabled |
|---------|---------------|---------|
| Autocapture | ✅ / ❌ | ✅ / ❌ |
| Session Recording | ✅ / ❌ | ✅ / ❌ |
| Surveys | ✅ / ❌ | ✅ / ❌ |
| Heatmaps | ✅ / ❌ | ✅ / ❌ |
| Feature Flags | ✅ / ❌ | ✅ / ❌ |
| Web Vitals | ✅ / ❌ | ✅ / ❌ |
### Identifiers
- **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: ✅ / ❌
### Issues Found
✅ None detected
— or —
⚠️ [Issue description]
### Script Loading
- **Source:** [CDN/Self-hosted/NPM bundle/Custom proxy]
- **Loading:** [Async/Sync/Defer]
### Other Analytics Tools Detected
[List of recognized analytics, tracking, and marketing tools]
### Other External Scripts
[Third-party script domains not matched to known tools]/e//capture//s//decide/us.i.posthog.comeu.i.posthog.comapp.posthog.com## PostHog Implementation Summary
### Status
✅ Installed
### Implementation Type
Global window.posthog
### Configuration
- **Version:** 1.96.1
- **API Host:** https://us.i.posthog.com (US Cloud)
- **Project Token:** phc_abc123def456ghi789jkl012mno345
- **Persistence:** localStorage+cookie
### Features (Module Loaded → Feature Enabled)
| Feature | Module Loaded | Enabled |
|---------|---------------|---------|
| Autocapture | ✅ | ✅ |
| Session Recording | ✅ | ✅ |
| Surveys | ✅ | ❌ |
| Heatmaps | ❌ | ❌ |
| Feature Flags | ✅ | ✅ |
| Web Vitals | ✅ | ✅ |
### Identifiers
- **Distinct ID:** 018d4f2a-1234-7abc-def0-123456789abc
- **Session ID:** 018d4f2a-5678-7xyz-abc0-987654321xyz
### Feature Flags
- `new-checkout-flow` ✅
- `beta-features` ❌
### Network Activity
- Events endpoint: ✅
- Session recording: ✅
- Decide/flags endpoint: ✅
- Surveys endpoint: ✅
### Issues Found
✅ None detected
### Script Loading
- **Source:** CDN (us-assets.i.posthog.com)
- **Loading:** Async
### Other Analytics Tools Detected
- Google Tag Manager
- Google Analytics
- HubSpot
### Other External Scripts
- cdn.example-vendor.com## PostHog Implementation Summary
### 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
### Features (Module Loaded → Feature Enabled)
| Feature | Module Loaded | Enabled |
|---------|---------------|---------|
| Autocapture | ✅ | ❌ |
| Session Recording | ❌ | ❌ |
| Surveys | ✅ | ❌ |
| Heatmaps | ❌ | ❌ |
| Feature Flags | ✅ | ✅ |
| Web Vitals | ✅ | ❌ |
### Identifiers
- **Distinct ID:** (not accessible - bundled)
- **Session ID:** (not accessible - bundled)
### Network Activity
- Events endpoint: ✅
- Session recording: ❌
- Decide/flags endpoint: ✅
- Surveys endpoint: ✅ (module loaded, feature disabled)
### Issues Found
✅ None detected
### Script Loading
- **Source:** Custom proxy (ph.example.com)
- **Loading:** Bundled in app