# Share an Observable Framework Build — Data Apps at Your Own Link

Canonical: https://commareports.com/share-observable-notebook
Published: 2026-08-31

> Observable Framework builds a static dist/ of interactive data pages. Publish it to Comma for a private URL with anchored comments on the charts.

# Share an Observable Framework build

Observable Framework is a static site generator for data apps: markdown pages,
data loaders that run at build time, and Plot / D3 visualizations that stay
interactive in the output. `npm run build` writes a `dist/` that needs no
runtime — which is exactly the shape that should be easy to share, and mostly
is not, because the moment you need it behind a login you are standing up a
host.

## Build

```bash
npm run build          # → dist/
```

The data loaders execute during the build, so `dist/` contains the _results_ —
no database credentials travel with it, and no server is needed to serve it.

## Publish dist/

Drag `dist/` (or a zip of it) into [the app](https://commareports.com/):

- `index.html` becomes the **report body**.
- The generated data files, JS bundles, styles and fonts upload as assets,
  and their references are rewritten to the uploaded copies.
- Scripts run inside a sandboxed iframe (`allow-scripts`, no
  `allow-same-origin`), so charts render, inputs respond and cross-filtering
  works.

Private by default, and access is set per report — private, team,
domain-gated, or a named reviewer list. See the
[sharing model](/docs/sharing).

## Refresh on a schedule

A data app that shows last month's numbers is worse than no data app. Rebuild
and PATCH the same report id:

```bash
npm run build

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 title "Metrics — week of $(date +%Y-%m-%d)" \
        '{title: $title, html: $html}')"
```

Or let a [routine](/features/routines/scheduled-html-reports) do it: same
report id, same URL, a revision per refresh, and nobody has to remember.

## What review adds

- **Anchored threads** on the chart — the question about the anomaly attached
  to the anomaly. See [commenting on HTML](/comment-on-html).
- **Revisions**, so week-over-week movement is visible in the report's own
  history rather than reconstructed from screenshots.

## Limits

- **Entry HTML: 5 MB.** Assets: 25 MB per file, 250 MB and 500 files total.
  A build that bakes in a large dataset is the one to watch — pre-aggregate in
  the loader.
- **60 requests/minute per token.**

## Try it

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

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

### Related

- [Share a Jupyter notebook](/share-jupyter-notebook-html) · [Share a marimo notebook](/share-marimo-notebook)
- [Share a Plotly HTML file](/share-plotly-html) · [Share a Vega-Lite chart](/share-vega-lite-chart)
- [Scheduled reports](/features/routines/scheduled-html-reports) · [Interactive HTML reports](/interactive-html-reports)
