Skip to content

Content Security Policy

If your site sends a Content-Security-Policy header, the browser only loads scripts and makes requests you have allowed. Everything from Launch runs from our domains, so a policy that lists only your own site blocks it. Nothing breaks visibly: the script simply never runs, and a widget may render without its styles.

This page lists exactly what to allow. It was checked in Chrome against a page with a strict policy on 19 September 2026.

Add only the parts you use.

You useDirectiveValue
Web analyticsscript-srchttps://e.nordva.dev
Web analyticsconnect-srchttps://e.nordva.dev
A widget (waitlist, feedback, changelog, notification bell, feedback board)script-srchttps://cdn.nordva.dev
A widget, or your own form calling the APIconnect-srchttps://api.nordva.dev
Changelog entries with cover images or images in the textimg-srcThe host your images are on (Launch stores no images)

A policy for a site using the analytics script and the waitlist widget:

Content-Security-Policy:
default-src 'self';
script-src 'self' https://e.nordva.dev https://cdn.nordva.dev;
connect-src 'self' https://e.nordva.dev https://api.nordva.dev;

Keep the rest of your policy as it is.

The widgets style themselves with a constructed stylesheet, which a policy treats as script, not as an inline style, so style-src needs nothing. Browsers without that feature (before Chrome 73, Safari 16.4 or Firefox 101) fall back to a <style> element, which a strict style-src blocks; the widget still works, without its styling. Widget versions: waitlist 1.4.0, feedback 1.2.0, changelog 1.2.0 and later; the notification bell and changelog 2.0 (every display mode, the launcher, the count on your own menu item and the announcement) work this way inside their own shadow roots, and were checked in Chrome under default-src 'none'; script-src 'self'; style-src 'self'; so was the feedback board widget (board.js 1.0.0, 30 September 2026). None of them sets a style attribute or writes HTML.

Launch’s script tag carries no inline code, so a nonce on it is optional. If your policy uses strict-dynamic, a nonce on the tag is the simplest way to let it load.

Or allow nothing: serve it from your own domain

Section titled “Or allow nothing: serve it from your own domain”

If you would rather not name our hosts in your policy, pass the analytics script and its requests through a path on your own domain. Then script-src 'self' and connect-src 'self' are enough, and ad blockers that block analytics hosts stop dropping visits as well.

Open Insights in the dashboard: under the script tag, “Serve it from your own domain” creates the proxy key and shows the tag for the proxied path. The server recipes are in Serve analytics from your own domain.

This covers analytics. Widgets still load from cdn.nordva.dev and post to api.nordva.dev, so a site that uses them needs those two in the policy.

  1. Open your site with the developer console visible.
  2. A blocked resource says so plainly: “Refused to load the script ‘https://e.nordva.dev/v1/s.js’ because it violates the following Content Security Policy directive”.
  3. Fix the directive it names, reload, and confirm the console is quiet.

To find out what a new policy would break before you enforce it, send it as Content-Security-Policy-Report-Only first: the browser reports violations without blocking anything.

Some hosts add a policy for you. If you didn’t write one and still see violations, look at:

  • Cloudflare: Rules, then Transform Rules, then Response Header Transform Rules.
  • Vercel and Netlify: the headers section of your project’s configuration file.
  • A framework or plugin that sets security headers by default.

Browser extensions that block trackers are a different thing: they block requests without any policy, and the person using the browser decides that. Serving the script from your own domain is what keeps those visits counted.