Manifest V3 enforces a strict default Content Security Policy that blocks remote script loading entirely inside extension pages - you cannot add cdn.mxpnl.com to script-src and run the normal remote snippet. Bundle the Mixpanel SDK as a local file inside the extension package and load it as a same-origin script, then whitelist only the network endpoints (api.mixpanel.com, api-js.mixpanel.com) in connect-src for the actual track/identify HTTP calls.
Why this happens
Browser extensions are sandboxed under a much stricter CSP than regular web pages, specifically to stop a compromised remote script from taking over extension privileges. Manifest V3 disallows remotely-hosted or eval-using code inside the extension's own pages and background scripts by default. Mixpanel's standard web snippet assumes it can load a .js file from Mixpanel's CDN and run in a normal page context, which Manifest V3 extension contexts forbid - the failure looks like a generic CSP violation in the console, not something Mixpanel-specific.
Fix it
- Do not use the CDN-hosted async snippet inside extension pages; install the Mixpanel npm package and bundle it into your extension build (webpack/esbuild/rollup) so the code is packaged locally and counted as same-origin.
- In manifest.json, add only the network hosts you need to
content_security_policy.extension_pagesunderconnect-src- you do not need script-src exceptions once the library is bundled locally. - If tracking runs from a content script injected into third-party pages, remember it executes in the host page's CSP context too - test on a page with a strict CSP, not just a permissive one.
- Avoid any Mixpanel SDK configuration option that dynamically injects a second script tag at runtime - it fails under MV3's stricter rules the same way the original CDN snippet does.
How to verify it worked
Load the unpacked extension in Chrome, open the extension's background/service-worker console, and confirm no "Refused to load the script" or "Refused to connect" CSP violation appears when a tracked action fires. Confirm the corresponding event lands in Mixpanel Live View.