Skip to content

Content Security Policy

The script-src and connect-src entries the tracking script needs, for statsy.co or for your own proxy host.

If your site sends a Content Security Policy, it has to allow the script to load and to send its data. Two directives are involved, and both take the same origin.

The entries

Content-Security-Policy
script-src 'self' https://statsy.co;
connect-src 'self' https://statsy.co;

script-src covers /js/script.js and the modules it loads from the same origin when you have them turned on: heatmaps, session replay, web vitals and widgets. Allow the origin rather than a single file, or those features fail silently.

connect-src covers the beacons the script sends: pageviews and goals to /api/collect, the mode lookup on /api/mode, replay chunks on /api/replay/…, and widget data on /api/widget/….

With a proxy host

Serving the script from your own domain changes both entries to that host, and you can drop https://statsy.co entirely:

Content-Security-Policy
script-src 'self' https://s.yourstartup.com;
connect-src 'self' https://s.yourstartup.com;

See Serve the script from your own domain for the DNS record that makes this work.

img-src, and what you do not need

No img-src entry is needed. The script loads no images and no stylesheets from Statsy, uses no tracking pixel, and never frames anything, so img-src, style-src, font-src and frame-src can stay as they are for tracking alone. If your policy uses default-src without the two directives above, add them explicitly.

Nonces and widgets

The tag itself is an external script with no inline code, so it works under a nonce-based policy: put your nonce on the tag as you would on any other script. One exception is worth knowing. A Statsy widget renders inside a shadow root with its own generated <style> element, so a policy with a strict style-src and no 'unsafe-inline' will block the widget’s styling. Pageview tracking is not affected.

Tip. When something is blocked, the browser console names the directive that did it. Check there first: an ad blocker fails quietly, while a policy violation always says so.

Last updated · Markdown version