Skip to content
whovisited.

Implementation · Security

Allow a website analytics tracker through your Content Security Policy

Find the CSP directives that control an analytics script and its event requests, test changes in report-only mode, and diagnose blocked collection safely.

A script can be allowed while its requests are blocked

A Content Security Policy (CSP) can stop an analytics installation at two separate points. The browser may refuse to load the external JavaScript file, or it may load the file but block the network requests that send events. The first problem is governed by a script directive; the second is governed by a connection directive. Fixing only one can leave tracking incomplete.

For the standard WhoVisited installation, the page loads `https://whovisited.net/tracker.js`. The tracker then uses `fetch()` to request `/api/v1/bootstrap` and `/api/v1/events` from the same origin. That means the browser needs permission for the script source and for connections to `https://whovisited.net`. CSP allows those resources only if the effective policy permits them.

Check script-src and connect-src

The `script-src` directive controls which JavaScript sources are permitted. If a policy has a more specific `script-src-elem` directive, that directive applies to script elements. The `connect-src` directive controls script-initiated connections such as `fetch()`. If either directive is absent, CSP may fall back to `default-src`; a strict `default-src 'self'` can therefore block both the external script and its API requests.

http
Content-Security-Policy: default-src 'self'; script-src 'self' https://whovisited.net; connect-src 'self' https://whovisited.net

This is a small illustration of the required source host, not a complete policy to paste over your existing header. Preserve the sources your site already needs, then add `https://whovisited.net` to the effective script and connection source lists. If `script-src-elem` or another policy header is present, check it too. Multiple enforced CSP policies apply together, so a second permissive header does not cancel a restriction in the first one.

Do not add `'unsafe-inline'` or a broad `https:` wildcard just to make one tracker load. If your site uses nonces, hashes, or `strict-dynamic`, ask the person who owns the policy to choose a narrow change that fits that design. A strict CSP is intentionally more complex than adding a hostname to a simple allowlist.

Try the change without enforcing it first

If you can test in staging, first send a `Content-Security-Policy-Report-Only` header containing a copy of your current policy with the proposed host added. Report-only mode records policy violations in the browser developer console without blocking the resources under that policy. Keep the current enforcing header in place while you test. On a site with several third-party scripts, copy the complete existing policy into the report-only version; a policy that lists only the tracker can produce unrelated warnings for the rest of the page.

  1. Open a staging page where the WhoVisited snippet is installed and open the browser's Network and Console panels.
  2. Reload the page. Look for `tracker.js`, then requests to `/api/v1/bootstrap` and `/api/v1/events` on `whovisited.net`.
  3. Check the Console for a CSP violation and its blocked URL and directive. A script violation points to the script source list; a connection violation points to `connect-src` or its fallback.
  4. After reviewing legitimate violations from the full site, add the narrow change to the enforcing policy and repeat the request check.

Report-only tests do not prove that the enforced policy will work: make the final check after changing the actual response header or meta policy. Also inspect the browser Network panel for the final response status. A successful request can still be rejected by the server, while a missing request can be caused by a browser extension, network failure, or consent state rather than CSP.

Use the failed request to find the next step

  1. No `tracker.js` request and a script CSP violation: add the provider host to the effective script source list, preserving your existing policy design.
  2. `tracker.js` loads but bootstrap or event requests show a CSP violation: add the provider origin to the effective connection source list.
  3. Requests appear with HTTP errors: inspect the response and WhoVisited installation settings; this is not fixed by broadening CSP.
  4. No CSP violation and no request: check consent, Do Not Track or Global Privacy Control, extensions, and whether the snippet runs on that page.
  5. Requests succeed but the dashboard stays empty: confirm the website and site ID, then use the product's installation verification and allow time for the report to refresh.

Once the script and both API requests are permitted, visit your deployed page and use WhoVisited's Verify installation action. An Integrated result means a matching event reached the service; it does not prove that every page is configured or that future requests cannot be blocked. For the normal installation sequence, see the WhoVisited installation guide.

Keep the policy narrow and verify the real page

CSP behavior depends on the complete policy delivered by your server or CDN, including any additional response headers and a meta policy. Browser developer tools show what happened for the page you tested, not every route, browser, extension, or visitor choice. Keep the policy narrow, test representative routes after deployment, and retain consent and privacy controls independently of the CSP change.

The key distinction is simple: `script-src` permits the tracker file, while `connect-src` permits the tracker's `fetch()` requests. Check both against the effective policy, then verify the outcome on your actual deployed site.

References and further reading

  1. MDN: Content-Security-Policy script-src directive
  2. MDN: Content-Security-Policy connect-src directive
  3. MDN: Content-Security-Policy-Report-Only header
  4. WhoVisited: How to install and verify WhoVisited analytics