If your site sends a Content-Security-Policy header, TrueStat needs two
directives, not one. Allowing only the script is the most common mistake here,
and it produces a failure with no visible symptom: the script loads without
error, and every event is silently blocked.
What to allow
Both directives:
Content-Security-Policy: script-src 'self' https://truestat.io; connect-src 'self' https://truestat.io;| Directive | Why |
script-src | Lets the browser load t.js. |
connect-src | Lets the script send events. This is the one people miss. |
If you already have a longer policy, add https://truestat.io to both
directives rather than replacing them.
Where to put it
| Platform | Where |
| Next.js | next.config.ts → headers() → a Content-Security-Policy entry |
| Vercel | vercel.json → headers array |
| Netlify | a _headers file, under /* |
| Nginx | add_header Content-Security-Policy "…" always; |
| Apache | .htaccess → Header set Content-Security-Policy "…" |
| WordPress | your security plugin's HTTP headers section (Wordfence, Sucuri, WP Cerber), or a header() call in a child theme's functions.php |
| No server access | <meta http-equiv="Content-Security-Policy" content="…"> in <head> — but read the trap below |
Two traps
A meta tag only works if no server header is already set. Server headers win over meta tags. If your host sets a CSP header and you add a meta tag to relax it, nothing changes and it looks like our script is broken.
Check first, from a terminal:
curl -sI https://example.com | grep -i content-security-policyIf that prints anything, the meta tag route is not available to you.
Two CSP headers do not merge permissively — they intersect. Browsers apply the most restrictive combination of every policy present. Adding a second, looser header does not loosen the first. If you have two, you have to edit the restrictive one.
How to tell this is your problem
Open DevTools with your site loaded. A CSP block always announces itself in the Console, with a message naming the directive:
Refused to connect to 'https://truestat.io/api/events' because it violates
the following Content Security Policy directive: "connect-src 'self'".That exact message means: script-src is fine, connect-src is not. Add
https://truestat.io to connect-src.
If the message names script-src instead, t.js never loaded at all.
Browser console showing the CSP violation message for connect-src, blocking the POST to /api/events. Dark DevTools theme, cropped to the message.
The shorter fix
If editing headers is awkward — a managed host, a security plugin you would
rather not touch, a policy someone else owns —
serving the script from your own domain removes the problem
entirely. Once both t.js and /api/events are on your origin, 'self' covers
them and your CSP needs no TrueStat entry at all.
That is often less work than negotiating a header change, and it also gets you past ad blockers.
If you proxy through a separate subdomain, 'self' does not cover it — both
directives must name the subdomain:
script-src 'self' https://a.example.com; connect-src 'self' https://a.example.com;What we do not need
TrueStat needs no unsafe-inline, no unsafe-eval, no img-src entry, no
style-src entry and no frame permissions. If a guide tells you to add any of
those for analytics, it is not describing this script.