Content Security Policy for Analytics Scripts — What to Allow and Why
A strict Content Security Policy blocks third-party analytics until you allow it. Learn which directives a tracking or session replay script needs, how to read CSP violations, and how to allow analytics without weakening your policy.
Short answer: a Content Security Policy tells the browser which origins a page may load scripts from and send data to. An analytics script needs two permissions: script-src for the origin that serves the script, and connect-src for the origin it sends data to. Add those specific origins. Do not loosen the policy with wildcards or unsafe-inline to make a script work.
Table of Contents
- What CSP Does
- What an Analytics Script Needs
- Reading a Violation
- Doing It Safely
- Session Replay and CSP
- Key Takeaways
What CSP Does
A Content Security Policy is a response header listing what a page is permitted to load and contact. Its main purpose is to limit the damage of injected scripts: if an attacker manages to insert a script tag, the browser refuses to run it unless its origin is allowed.
That protection applies to every script, including the ones you add on purpose. A third-party tool will not work until the policy permits it.
What an Analytics Script Needs
| Directive | Controls | Needed for |
|---|---|---|
script-src | Where scripts may load from | The loader and SDK bundle |
connect-src | Where the page may send requests | Event batches posted back |
img-src | Where images may load from | Only if the tool uses an image beacon |
worker-src | Where workers may load from | Only if the tool uses a web worker |
For DeepSync, the docs state it directly: allow the ingest origin in both script-src and connect-src, the first for the loader and SDK bundle, the second for the event batches the SDK posts back (Next.js install, CSP section).
An example, with a placeholder origin:
Content-Security-Policy:
default-src 'self';
script-src 'self' https://ingest.example.com;
connect-src 'self' https://ingest.example.com;Use the actual origin from your project's snippet. Keep your other directives as they are.
If connect-src is not set, it falls back to default-src. A site with default-src 'self' and a script allowed only in script-src will load the script and then block every request it makes. That produces the confusing result of a script that is present and records nothing.
Reading a Violation
When CSP blocks something, the browser console says so. A message names the directive and the blocked address, along the lines of: refused to connect to an address because it violates the connect-src directive.
To diagnose:
- Open the browser console on your site.
- Look for messages mentioning Content Security Policy.
- Note the directive and the blocked origin.
- Add that origin to that directive.
- Reload and repeat until clean.
Two aids:
- Report-only mode. Sending the policy as
Content-Security-Policy-Report-Onlylogs violations without blocking, which lets you test a change safely before enforcing it. - Violation reporting. A reporting endpoint collects violations from real visitors, catching cases you did not reproduce.
Check the network panel too. A blocked request is listed as blocked, with the reason.
Doing It Safely
- Allow specific origins, with scheme and host. Not
https:and not*. - Do not add `unsafe-inline` to `script-src` to make a snippet work. That removes most of CSP's protection.
- Prefer an external script tag to an inline snippet. A single external loader needs only an origin in
script-src. - If you need inline code, such as a command-queue stub, use a nonce or a hash for that block.
- Check every route. Policies are sometimes set per path. An unlisted route may have a stricter one.
- Check all the places a policy can come from: the server, the CDN, a meta tag, and the hosting platform. More than one can apply, and the strictest combination wins.
- Review what you are allowing. Adding an origin means trusting it to run code on your pages. Confirm what the script does (what a tracking script sends).
- Remove origins for tools you have stopped using.
Session Replay and CSP
Two further points for replay tools.
Recording. The recorder runs as a script in your page and posts data to the ingest origin. Beyond script-src and connect-src, it normally needs nothing else.
Replaying. A recording references your site's styles, fonts, and images, sometimes loading them from their original addresses when someone watches. Stylesheets and fonts on another domain need to permit cross-origin use for playback to render correctly. That is governed by cross-origin resource sharing headers on those assets, not by your page's CSP, and it is why a replay can show wrong fonts or missing styles (capture limits).
Injected scripts. Tools that inject a script into a page they do not control, such as an automated tester adding a loader, can be refused by a strict policy. That is the policy working as designed.
A tag manager complicates CSP considerably, because it loads further scripts you must also allow. A direct tag keeps the policy short.
A script that loads and records nothing is usually connect-src
Check the console for a blocked request before investigating anything else.
Key Takeaways
- Analytics needs
script-srcandconnect-srcfor a specific origin. - A missing
connect-srccauses a script that loads and sends nothing. - Read violations in the console and test with report-only mode.
- Never weaken the policy with wildcards or
unsafe-inline.
Conclusion
A Content Security Policy and analytics are compatible. Allow exactly the origins the script needs, and your policy stays as strict as it was.
Frequently Asked Questions
Related articles
Stay in the loop
Get the latest insights on product analytics and user behavior delivered to your inbox.



