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.
What to allow
Section titled “What to allow”Add only the parts you use.
| You use | Directive | Value |
|---|---|---|
| Web analytics | script-src | https://e.nordva.dev |
| Web analytics | connect-src | https://e.nordva.dev |
| A widget (waitlist, feedback, changelog, notification bell, feedback board) | script-src | https://cdn.nordva.dev |
| A widget, or your own form calling the API | connect-src | https://api.nordva.dev |
| Changelog entries with cover images or images in the text | img-src | The 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.
Styles
Section titled “Styles”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.
Nonces and hashes
Section titled “Nonces and hashes”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.
Checking it
Section titled “Checking it”- Open your site with the developer console visible.
- 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”.
- 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.
Where the policy comes from
Section titled “Where the policy comes from”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
headerssection 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.