# Share a D3 Visualization — With the Interaction Intact

Canonical: https://commareports.com/share-d3-visualization
Published: 2026-09-08

> A D3 visualization is the interaction. Publish it to Comma for a URL where the brush, the zoom and the transitions still work — instead of a GIF of them.

# Share a D3 visualization

D3 is not a charting library, which is exactly why sharing one is harder than
sharing a chart. You did not build a picture of the data — you built a force
simulation somebody is supposed to drag, a brushable timeline they filter with,
a zoomable treemap that only makes its point at the third level down.

None of that survives a screenshot, and a GIF of you using it is a
demonstration, not a tool.

## The two ways it breaks in transit

**Data loading.** The common pattern loads data at runtime:

```javascript
const data = await d3.csv("sales.csv");
```

From a `file://` origin, the browser blocks that fetch as a cross-origin
request. So the page opens, the SVG element exists, and nothing is ever drawn —
with the failure only visible in the console. This is the single most common
reason a colleague reports "your chart is blank" for a file that works fine on
your machine. See [why HTML reports go blank](/fix/plotly-chart-not-showing-in-html)
for the general shape of it.

**Library loading.** An `http://` CDN script inside an `https://` page is
blocked as [mixed content](/fix/mixed-content-blocked-html-report), silently.

## Publish the folder

Drop the whole directory — the HTML, the data files, any local modules — into
[the app](https://commareports.com/):

- `index.html` becomes the **report body**.
- `sales.csv`, your JS modules and any images upload alongside it, with
  relative references rewritten to the uploaded copies. `d3.csv("sales.csv")`
  now resolves, which is the step `file://` cannot do.
- Scripts run inside a sandboxed iframe (`allow-scripts`, no
  `allow-same-origin`), so the simulation runs, the brush brushes, and the
  transitions animate.

Or PATCH the entry file from a build script:

```bash
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 dist/index.html \
        --arg t "Supply chain — dependency graph" '{title: $t, html: $html}')"
```

## Inline the library for anything durable

```html
<script src="https://cdn.jsdelivr.net/npm/d3@7"></script>
```

is fine for a draft and a liability for a report attached to a decision. `@7`
is a moving target, and the CDN is a third party you have no agreement with.
For a visualization that has to render the same way next year, bundle D3 into
the page — `esbuild --bundle --minify` over an entry that imports it is the
short version.

## From Observable

Observable notebooks are the most common source of D3 work and the most
awkward to hand over: a viewer needs an account for a private notebook, and a
published one lives on somebody else's domain with their branding.

Export instead — Observable's download-as-tarball, or the runtime embed —
which gives you a self-contained folder. Publish that folder and the notebook
renders at your URL, under your access controls, with a comment thread on it.

## What review adds

- **Anchored threads** on a cluster or an outlier — see
  [commenting on HTML](/comment-on-html).
- **Revisions**, so a visualization rebuilt against new data keeps one link.
- **Access per report** — private, team, domain-gated or named reviewers. See
  the [sharing model](/docs/sharing).

## Limits

- **Entry HTML: 5 MB.** Assets: 25 MB per file, 250 MB and 500 files total. The
  dataset is usually the file to watch — pre-aggregate rather than shipping raw
  rows the visualization immediately bins anyway.
- **60 requests/minute per token.**

## Try it

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

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

### Related

- [Share a Chart.js chart](/share-chartjs-chart) · [Share a Highcharts chart](/share-highcharts-chart)
- [Share an Observable notebook](/share-observable-notebook) · [Share a Vega-Lite chart](/share-vega-lite-chart)
- [Share an HTML folder](/share-html-folder) · [Interactive HTML reports](/interactive-html-reports)
