# Share a Plotly Chart as a Link — Interactive, Not a Screenshot

Canonical: https://commareports.com/share-plotly-html
Published: 2026-08-23

> fig.write_html() gives you an interactive chart trapped in a local file. Publish it to Comma for a URL where hover, zoom and legend toggles still work — and where a colleague can comment on the spike.

# Share a Plotly chart as a link

Plotly's whole value proposition is that the chart is interactive: hover for
the value, drag to zoom, click the legend to isolate a series. Then you share
it, and the interaction is the first thing to die. It becomes a PNG in Slack,
where nobody can check the number under the peak.

The self-contained HTML file that `write_html` produces already solves the
technical half. What it does not solve is that the file lives on your disk.

## Publish it

```python
import plotly.express as px, requests, os

fig = px.line(df, x="day", y="signups", color="channel")
fig.write_html(
    "chart.html",
    include_plotlyjs="https://cdn.jsdelivr.net/npm/plotly.js-dist-min@2/plotly.min.js",
)

requests.post(
    "https://commareports.com/api/v1/reports",
    headers={"Authorization": f"Bearer {os.environ['COMMA_API_TOKEN']}"},
    json={"title": "Signups by channel", "html": open("chart.html").read()},
).raise_for_status()
```

Two ways to handle the library, both fine:

- **Inline** (`include_plotlyjs=True`) — one truly self-contained file, about
  3.5 MB of plotly.js, still under the 5 MB HTML cap on its own but tight if
  you have a lot of data points.
- **CDN** — use jsdelivr, unpkg, cdnjs or esm.sh as above. Plotly's default
  `"cdn"` value points at an origin Comma's CSP does not allow, so pass the
  full jsdelivr URL instead and the chart loads in a few KB of HTML.

## Make it a report, not a chart

A lone figure rarely answers a question. Compose the document instead:

```python
parts = [fig.to_html(full_html=False, include_plotlyjs=False) for fig in figs]
html = f"""<!doctype html><meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/plotly.js-dist-min@2/plotly.min.js"></script>
<h1>Weekly growth</h1>
<p>Paid signups fell 12% after the pricing change; organic is flat.</p>
{"".join(parts)}"""
```

Now there is prose to anchor comments to, which is what turns a chart into a
decision. See [commenting on HTML](/comment-on-html).

## Limits

- **HTML body: 5 MB.** Big traces add up fast — downsample, or split into
  several reports.
- **Scripts run, sandboxed:** `allow-scripts`, no `allow-same-origin`.
  Script and style CDNs are limited to jsdelivr, unpkg, cdnjs and esm.sh.
- **60 requests/minute per token.**

## Try it

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

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

### Related

- [Interactive HTML reports](/interactive-html-reports) — what survives the sandbox
- [Share a Bokeh plot](/share-bokeh-plot) · [Share a Folium map](/share-folium-map)
- [EDA reports](/share-eda-report) · [Jupyter](/with/jupyter)
