Overview
A Content Security Policy (CSP) works like a whitelist for your website. It tells the browser which domains are allowed to load scripts, styles, images, and frames. If your CSP does not include Termly's domains, your consent banner and preference center may fail to load or may not work as expected.
This guide lists exactly which rules to add so Termly runs correctly on sites with a strict CSP.
How to tell if CSP is the cause
If your CSP is blocking Termly, you will usually see browser console errors that mention blocked connections or ignored directives. Common examples:
- "Refused to connect to 'https://eu.consent.api.termly.io' because it violates the following Content Security Policy directive: connect-src..."
- "The directive 'frame-ancestors' is ignored when delivered via an element."
These messages mean your CSP is too restrictive. When the banner's network calls are blocked, your visitors' consent choices cannot be saved, so the banner reappears on every page load.
Is Termly compatible with a strict CSP?
Yes. Termly works with a strict CSP. You only need to whitelist a few Termly domains and allow inline styles for the banner and the Global Privacy Control (GPC) toast.
What to add
Add or update the following directives in your CSP header:
Content-Security-Policy: script-src 'self' https://app.termly.io; connect-src 'self' https://app.termly.io https://us.consent.api.termly.io https://eu.consent.api.termly.io; style-src 'self' https://app.termly.io 'unsafe-inline'; img-src 'self' https://app.termly.io data:; frame-src 'self' https://app.termly.io; frame-ancestors 'self';
If the following does not already appear in your CSP header, please add it separately:
X-Frame-Options: SAMEORIGIN
What each rule does
script-src (https://app.termly.io) This is where the main Termly script (embed.min.js) loads from. Without it, the banner cannot start.
connect-src (https://app.termly.io, https://us.consent.api.termly.io, https://eu.consent.api.termly.io) These endpoints fetch your banner configuration, save consent choices, and log statistics. If they are blocked, consent cannot be stored.
style-src (https://app.termly.io plus 'unsafe-inline') Inline styles are used for the banner layout and the GPC toast. If inline styles are blocked, the banner may look broken or the GPC toast may not appear.
img-src (https://app.termly.io plus data:) Logos and static images load from Termly. The policy viewer also uses base64 (data:) background images.
frame-src (https://app.termly.io) The policy viewer and embedded policies load inside an iframe served by Termly.
A note on security: Termly requires 'unsafe-inline' for styles only. Termly does not require 'unsafe-eval'.
A simpler option
If you prefer broader rules, you can use:
default-src 'self' https://app.termly.io;
This covers most cases. Teams running a strict CSP usually prefer the explicit per-directive rules above.
Full example
This is a template only. Please merge it with your existing CSP and any other third-party requirements your site already has.
Content-Security-Policy: default-src 'self'; script-src 'self' https://app.termly.io; connect-src 'self' https://app.termly.io https://us.consent.api.termly.io https://eu.consent.api.termly.io; style-src 'self' https://app.termly.io 'unsafe-inline'; img-src 'self' https://app.termly.io data:; frame-src 'self' https://app.termly.io; font-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self';
If the banner still does not load after applying these rules, please reach out and we will be glad to help.