# Share an ECharts HTML File — Vendor the Library, Keep the Interaction

Canonical: https://commareports.com/share-echarts-html
Published: 2026-08-31

> An ECharts page that loads the library from a CDN can render blank when the CDN is blocked. Vendor echarts.min.js, publish to Comma, and the chart stays interactive.

# Share an ECharts HTML file

ECharts produces some of the best interactive charts on the web, and an
exported ECharts page has one dependency that ruins it in transit: a
`<script src="https://cdn…/echarts.min.js">` tag.

Send that file to someone on a locked-down network, or open it anywhere the
CDN is unreachable, and you get a blank div. The chart data is right there in
the file; the renderer never arrives.

## Vendor the library

Download it once and reference it relatively:

```bash
curl -fsSLO https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js
```

```html
<script src="echarts.min.js"></script>
```

From **pyecharts**, point the asset host at a local path before rendering so
the generated HTML does the same:

```python
from pyecharts.globals import CurrentConfig
CurrentConfig.ONLINE_HOST = "./"          # emit ./echarts.min.js, not a CDN URL

chart.render("chart.html")
```

Then copy `echarts.min.js` next to `chart.html`.

## Publish both files

Drag `chart.html` and `echarts.min.js` together into
[the app](https://commareports.com/):

- `chart.html` becomes the **report body**.
- `echarts.min.js` uploads as an asset and the `<script src>` reference is
  rewritten to the uploaded copy — the step that makes the chart independent
  of any CDN.
- Scripts run inside a sandboxed iframe (`allow-scripts`, no
  `allow-same-origin`), so dataZoom, tooltips, legend filtering and the
  toolbox export all work.

The recipient gets a working chart, not a blank rectangle and a request to
"try a different browser".

## Refresh it

```bash
python build_chart.py      # → chart.html

curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html chart.html \
        --arg title "Traffic — $(date +%Y-%m-%d)" '{title: $title, html: $html}')"
```

The vendored script stays attached to the report, so subsequent refreshes only
need to replace the entry HTML. A
[routine](/features/routines/scheduled-html-reports) can run the whole thing
on a cadence.

## What review adds

- **Anchored threads** on the chart — the question about the spike attached to
  the spike. See [commenting on HTML](/comment-on-html).
- **Revisions**, so week-over-week comparison does not depend on someone having
  kept the old screenshot.

## Limits

- **Entry HTML: 5 MB.** A chart with a large inlined dataset is the case that
  gets close — downsample, or move the series into a JSON asset.
- Assets: 25 MB per file, 250 MB and 500 files total.
- **60 requests/minute per token.**

## Try it

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

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

### Related

- [Share a Plotly HTML file](/share-plotly-html) · [Share a Bokeh plot](/share-bokeh-plot)
- [Share an Altair chart](/share-altair-chart) · [Share a Vega-Lite chart](/share-vega-lite-chart)
- [Why report CSS breaks](/html-report-broken-css) · [Interactive HTML reports](/interactive-html-reports)
