The chart disappeared once the report was hosted

It rendered on your machine. It renders from the build directory. Serve it over HTTPS and the chart is an empty box, or the page is unstyled.

Open the console. One of two messages is waiting.

Message 1 — mixed content

Mixed Content: The page at 'https://…/report' was loaded over HTTPS,
but requested an insecure resource 'http://cdn.example.com/plotly.min.js'.
This request has been blocked; the content must be served over HTTPS.

An HTTPS page asked for an HTTP subresource. Browsers block active mixed content — scripts, stylesheets, iframes, fetch/XHR, web fonts — with no user override left in modern Chrome, Firefox or Safari. Passive content (images, video) is increasingly auto-upgraded to HTTPS and blocked if that fails.

This never fires locally, because file:// and http://localhost are not HTTPS pages. The bug is created by hosting, which is the first moment anyone but you is looking.

Where the http:// comes from: a hard-coded CDN URL in a report template, an old tool version that predates the CDN's HTTPS support, a company asset host that never got a certificate, or a config value someone typed once in 2019.

Fix:

  • Change the URL to https://. Every major CDN — jsDelivr, unpkg, cdnjs, esm.sh — serves HTTPS.
  • Or stop linking it at all: include_plotlyjs=True (Plotly), chart.save(..., inline=True) (Altair), --embed-images (nbconvert), Extent's offline mode. Embedded resources cannot be mixed content, and they survive an offline reader as well.

Message 2 — a policy refusal

Refused to load the stylesheet 'https://cdn.example.com/style.css'
because it violates the following Content Security Policy directive:
"style-src 'self'".

Different cause entirely. The resource is HTTPS and fine; the page's host declares a Content-Security-Policy that does not allow it. CI artifact viewers are where people meet this — Jenkins most famously, covered in the Jenkins CSP fix, and GitLab's and Azure's viewers have their own constraints.

Fix: you generally cannot loosen someone else's CSP, and you should not want to. Stop using the artifact viewer as a rendering surface — it is a file store that happens to return text/html.

Telling them apart quickly

Console says Cause Fix
…requested an insecure resource… Mixed content Make the subresource HTTPS, or embed it
Refused to … violates … Content Security Policy Host CSP Change where it is hosted
404 on .css / .js Missing assets Publish the folder
CORS error against file:///… Opaque origin Serve it over HTTP

Four distinct bugs that all present as "the report looks broken". The console names which one you have — it is the fastest diagnostic in this entire class of problem.

The durable arrangement

Generate the report self-contained where you can, and publish the directory where you cannot. On a published report, scripts run inside a sandboxed iframe (allow-scripts, no allow-same-origin), so interactivity is preserved; subresources fetched inside that frame are not governed by the app's own CSP, and the common visualization CDNs are allow-listed. HTTPS CDN references work; http:// ones are still blocked by the browser, as they should be.

Assets uploaded with the entry file have their relative references rewritten to the uploaded copies, which removes the 404 row of that table at the same time.

Try it

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

Publish a report that renders for everyone →

Related