# Plotly Chart Missing From the Exported HTML — Every Cause

Canonical: https://commareports.com/fix/plotly-chart-not-showing-in-html
Published: 2026-09-07

> An exported Plotly figure that shows an empty div, a broken frame, or nothing at all. The include_plotlyjs modes, the offline case, the CSP case, and how to make the export self-contained.

# The Plotly chart isn't in the HTML

`fig.write_html("report.html")` succeeds. You open the file and get a
page with a chart-shaped hole in it — correct height, no chart. Or the
whole page is white.

The figure serialized fine. `plotly.js` didn't arrive.

## The four `include_plotlyjs` modes

This one argument decides whether the export survives leaving your
machine:

| Value         | What lands in the file                                   | Size                   | Survives offline?                       |
| ------------- | -------------------------------------------------------- | ---------------------- | --------------------------------------- |
| `'cdn'`       | `<script src="…cdn…">`                                   | ~3 MB → ~50 KB         | No                                      |
| `True`        | The whole bundle, inlined                                | ~3 MB                  | Yes                                     |
| `'directory'` | `plotly.min.js` written alongside, referenced relatively | small file, big folder | Only if the folder travels              |
| `False`       | Nothing                                                  | tiny                   | Only if the host page already loaded it |

`write_html` defaults to `'cdn'`. That default is why the chart works on
your laptop and vanishes on the reviewer's.

```python
fig.write_html("report.html", include_plotlyjs=True)  # self-contained
```

## Match the cause to the symptom

**Empty box where the chart should be, console shows a failed request
for `plotly-*.min.js`.** CDN mode plus no network: a plane, an air-gapped
environment, or a corporate proxy that blocks jsDelivr. Fix with
`include_plotlyjs=True`.

**Empty box, console says `Refused to load the script … violates the
Content-Security-Policy`.** The viewer serving the file has a strict
CSP. CI artifact viewers are the usual culprit — Jenkins especially, see
[the Jenkins CSP fix](/ci/jenkins-html-report). Inlining does not always
help here either, because a CSP without `'unsafe-inline'` refuses the
inline bootstrap too. The real fix is to stop treating the artifact
viewer as a rendering surface.

**Empty box, console shows a 404 for `plotly.min.js` in the same
directory.** `'directory'` mode, and only `index.html` travelled. Same
root cause as [a report that lost its CSS](/html-report-broken-css) —
publish the folder, not the entry file.

**Nothing renders and the console is clean, but the page is enormous.**
Several figures each inlining their own copy of the bundle. Inline once:

```python
parts = [fig.to_html(full_html=False, include_plotlyjs=(i == 0))
         for i, fig in enumerate(figs)]
html = "<html><body>" + "\n".join(parts) + "</body></html>"
```

**Chart renders in Jupyter, missing in the `nbconvert` output.** A
different problem — the notebook renderer versus the static export. See
[Jupyter widgets not rendering in HTML](/fix/jupyter-widgets-not-rendering-in-html).

## Making the export shareable

Once the file renders, the remaining question is how anyone else sees
it. Emailing a 3 MB self-contained HTML file mostly ends in a client
stripping the scripts ([why](/email-html-report)); a `file://` copy on
someone else's laptop reintroduces every problem above.

Publish it and send a URL. The interactivity survives: scripts run in a
sandboxed iframe (`allow-scripts`, no `allow-same-origin`), so zoom, hover,
legend toggles and the mode bar all work —
[interactive HTML reports](/interactive-html-reports). CDN subresources
inside that frame are not governed by the app's CSP, and the common
visualization CDNs are allow-listed, so `'cdn'` exports render too.

Then the reader can select a paragraph — or a table cell next to the
chart — and ask their question in place, rather than screenshotting the
plot into chat ([comment on HTML](/comment-on-html)).

## Try it

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

**[Publish a Plotly report →](https://commareports.com/)**

### Related

- [Share a Plotly HTML chart](/share-plotly-html)
- [My HTML report lost its CSS](/html-report-broken-css)
- [Jupyter widgets not rendering in HTML](/fix/jupyter-widgets-not-rendering-in-html)
- [Interactive HTML reports](/interactive-html-reports)
