Content Security Policy (CSP): Which Domains to Allow
If your site sends a Content-Security-Policy header (or meta tag) that does not include the Sealmetrics tracker domain, the browser will refuse to load the script and/or refuse to send the tracking beacon — and you will see zero data, even though the snippet is installed correctly.
Symptoms
- No requests to
t.sealmetrics.comin the Network tab, even though the<script>tag is in the HTML. - Console errors mentioning "Refused to load the script" or "Refused to connect" together with "because it violates the following Content Security Policy directive", naming
script-src,script-src-elem, orconnect-src. - In the Network tab, the request appears with a blocked status (Chrome shows
(blocked:csp)in the status column). typeof sealmetricsin the console returns"undefined"(the script never executed).
How the tracker uses the network
Two different CSP directives are involved, and both must allow the tracker host:
| Request | What it is | CSP directive that governs it |
|---|---|---|
GET https://t.sealmetrics.com/t.js?id=... | The tracker library itself | script-src (or script-src-elem) |
POST https://t.sealmetrics.com/event | The tracking beacon (one per pageview, conversion, or microconversion) | connect-src |
The beacon is sent with navigator.sendBeacon (with a fetch fallback), and both are governed by connect-src. The beacon always goes to the same host the script was loaded from, so one hostname covers both directives.
A common partial failure: script-src allows the domain but connect-src does not. The script loads and sealmetrics is defined, but every beacon is blocked — the console shows "Refused to connect" errors and no data arrives.
Solution
Add the tracker host to both directives in your CSP:
Content-Security-Policy:
script-src 'self' https://t.sealmetrics.com;
connect-src 'self' https://t.sealmetrics.com;
(Keep whatever other sources your policy already lists — the example only shows the Sealmetrics additions.)
If you use the first-party tracker
With the first-party tracker, the script is served from a subdomain of your own domain (e.g. metrics.yourstore.com) instead of t.sealmetrics.com. Allow that subdomain instead:
Content-Security-Policy:
script-src 'self' https://metrics.yourstore.com;
connect-src 'self' https://metrics.yourstore.com;
If your policy uses 'self' and the tracker subdomain shares your registrable domain, you still need to list the subdomain explicitly — 'self' only matches the exact origin of the page.
If your policy uses default-src only
script-src and connect-src fall back to default-src when not declared. In that case adding the tracker host to default-src is enough — but explicit script-src/connect-src entries are clearer and safer to maintain.
Verification
- Deploy the updated policy.
- Hard-reload the page (Cmd/Ctrl+Shift+R) with DevTools open.
- Console: no CSP violation mentioning
sealmetrics. - Network (filter
sealmetrics):t.jsreturns200and the/eventbeacon returns204 No Content. - Dashboard: the Last hit timestamp on the Overview report updates within seconds.
What NOT to do
- Do not add
'unsafe-inline'or wildcards (*) just to make the tracker work. Only the tracker host is needed; loosening the whole policy trades real security for nothing. - Do not move the snippet inline to bypass
script-src. The library must still be downloaded from the tracker host, and the beacon still needsconnect-src— an inline copy solves neither and breaks updates.
Related
- Tracker installation — the exact script URL for your site.
- First-Party Tracker — serving the tracker from your own subdomain.
- Troubleshooting overview — quick installation diagnostics.