Content Security Policy

Content Security Policy (CSP) is an HTTP response header that tells the browser which sources a page may load resources from. Anything outside the policy is blocked before the request goes out, and the browser writes a refusal to the console.

Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.jsdelivr.net;
  style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none'

The directives that decide whether a report renders

Directive Governs Symptom when it blocks
script-src JavaScript Dead tables, empty chart boxes
style-src CSS, including <style> Unstyled wall of text
img-src Images, data: URIs Broken image placeholders
connect-src fetch, XHR, WebSocket Blank shell — the data never loads
font-src Web fonts Fallback glyphs, shifted layout
frame-ancestors Who may frame the page Blank iframe in Notion/Confluence

Generated reports trip script-src most often, because nearly every chart library ships as a CDN <script> tag and nearly every corporate host allows only 'self'.

Reading a violation

The console message names the cause precisely:

Refused to load the script 'https://cdn.plot.ly/plotly-2.27.0.min.js'
because it violates the following Content Security Policy directive: "script-src 'self'".

That is a CSP block. This is not:

Mixed Content: The page at 'https://…' was loaded over HTTPS, but requested
an insecure resource 'http://…'. This request has been blocked.

That is mixed content, and the fix is different — see telling them apart.

Two ways to survive a strict host

  1. Vendor the dependency. Most generators can bundle the library into the output directory instead of linking a CDN — Plotly's include_plotlyjs="directory", Bokeh's CDNINLINE, Vega's local build. Same-origin scripts satisfy script-src 'self'.
  2. Publish where the report body is not subject to the site's policy. Serving report HTML inside a sandboxed iframe lets the report keep its own dependencies while the surrounding application keeps a strict policy of its own.

The second is how Comma serves report bodies: the page runs with allow-scripts and without allow-same-origin, so charts, filters and drill-downs work as they do locally without the report gaining access to the account around it (interactive HTML reports).

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history.

Publish an interactive report →

Related