# Upload an HTML File and Get a Link — Including the Folder It Came In

Canonical: https://commareports.com/upload-html-file-get-link
Published: 2026-08-28

> Turn an .html file into a URL you can send. Drag one file, a whole output directory, or a zip; keep the CSS and JS working; choose who can open it. No repo, no build, no bucket.

# Upload an HTML file, get a link

The file works on your machine and nowhere else. Here is the shortest
path from `report.html` to a URL you can paste into a message.

## 1. Work out what you actually have

Two shapes, and they upload differently.

**One self-contained file.** Everything inlined — `pandoc --embed-resources`,
`plotly.offline` with `include_plotlyjs="inline"`, an Evidently or
`ydata-profiling` report, a `df.style.to_html()` table. Upload the file.

**A directory.** An `index.html` next to a folder of CSS, JS and JSON.
This is what Playwright, Allure, Serenity, `genhtml`, `coverage html`,
Sphinx, MkDocs and `jupyter nbconvert --to html --template lab` produce.
Upload the _whole directory_. Uploading only `index.html` is the single
most common reason a published report renders as an unstyled skeleton —
see [why the report lost its CSS](/html-report-broken-css).

Not sure? Look next to the file. If there's a folder named `assets`,
`_static`, `data`, or the report's own name, you have a directory.

## 2. Drop it in

Drag onto [Comma](https://commareports.com/) — a file, a folder, or a
zip of the folder:

- `index.html` becomes the report body.
- Every asset uploads alongside, and the relative references inside the
  HTML are rewritten to point at the uploaded copies. This is the step
  that a plain file share, an email attachment and `file://` all skip,
  and it's why those three all end up looking broken.
- Scripts run inside a sandboxed iframe (`allow-scripts`, no
  `allow-same-origin`), so filters, sortable tables and charts keep
  working while the page can't touch your session. See
  [interactive HTML reports](/interactive-html-reports).

You get the URL as soon as the upload finishes.

## 3. Decide who can open it

Per report, not per account:

- **Private** — only you.
- **Team** — your workspace.
- **Anyone signed in** — useful for a company-wide read.
- **Anyone with the link** — and separately, whether link holders can
  view, comment, or edit.

The full model, including what an expired or revoked link does, is in
[sharing & access control](/docs/sharing).

## From a script, instead of a browser

```bash
curl -fsS -X POST "https://commareports.com/api/v1/reports" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html report.html \
        '{title: "Nightly report", html: $html}')"
```

The response carries the report id and its URL. `PATCH` the same id on
the next run and the URL stays put while the old version is kept as a
revision — which is how you get "did this get better or worse" without
building a dashboard. See [the API](/docs/api) and
[publishing from CI](/docs/ci).

Agents do the same thing through
[MCP](/mcp) instead of curl.

## Then: review, not screenshots

Once it's a URL, feedback lands on the report. Select a number, leave a
thread, and it stays anchored there across revisions — see
[commenting on HTML](/comment-on-html) and
[stop screenshotting reports](/stop-screenshotting-reports).

## Limits

Entry HTML 5 MB; assets 25 MB per file, 250 MB and 500 files per report;
60 requests/minute per token.

## Try it

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

**[Upload an HTML file →](https://commareports.com/)**

### Related

- [Where to host a single HTML file](/host-html-file) — every option compared
- [Someone sent me an HTML file](/open-html-file-online) · [Email an HTML report](/email-html-report)
- [Embed a report](/embed-html-report) · [Share an HTML report](/share-html-report)
