# Use Comma with Quarto: Render the Report, Then Get It Reviewed

Canonical: https://commareports.com/with/quarto

> Quarto renders .qmd to polished HTML — and stops there. Pipe the output to Comma for anchored comments, share roles, and revisions on a stable link. One curl call or one MCP tool.

# Use Comma with Quarto

Quarto is the best open-source way to turn markdown plus executable code
into a polished HTML document. It is deliberately not a collaboration
tool: `quarto render` ends with a file on disk, and what happens to that
file is your problem.

The usual answers — GitHub Pages, Quarto Pub, Netlify, an email
attachment — all host the document and none of them review it. Feedback
arrives in Slack as "the table in section 3 looks off," and you go
hunting for which table, in which render, of which week.

Comma is the review layer: POST the rendered HTML, get a share link, and
collect comments anchored to the exact paragraph or table cell being
discussed.

## The pipeline

### 1. Render self-contained HTML

Comma takes one HTML document, so embed the resources. In the `.qmd`
header:

```yaml
format:
  html:
    embed-resources: true
```

Then:

```bash
quarto render weekly-metrics.qmd
```

You now have `weekly-metrics.html` with styles and images inlined.

### 2. Publish it

The create endpoint takes JSON: an `html` field (required) plus optional
`title` and `description`. `jq -Rs` wraps the file into that shape:

```bash
jq -Rs '{title: "Weekly metrics — 2026-W24", html: .}' weekly-metrics.html |
  curl -s -X POST https://commareports.com/api/v1/reports \
    -H "Authorization: Bearer $COMMA_API_TOKEN" \
    -H "Content-Type: application/json" \
    --data-binary @-
```

The response:

```json
{
  "id": "9f1c…",
  "title": "Weekly metrics — 2026-W24",
  "created_at": "2026-06-10T08:00:00Z",
  "edit_url": "/r/9f1c…",
  "share_url": "/p/9f1c…"
}
```

Drop the `share_url` in your team channel. New reports default to
public-with-link, view-only; pass `"visibility": "private"` or
`"public_permission": "comment"` in the same body to change that at
create time. Tokens come from **Settings → API tokens** and are scoped
and revocable; HTML up to 5 MB.

### 3. Re-render into the same link

When the data refreshes or a reviewer's comment lands, render again and
PATCH instead of POST:

```bash
jq -Rs '{html: .}' weekly-metrics.html |
  curl -s -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
    -H "Authorization: Bearer $COMMA_API_TOKEN" \
    -H "Content-Type: application/json" \
    --data-binary @-
```

Comma stores the previous version as a revision, keeps the share URL
stable, and can diff runs. Reviewers' existing threads stay on the
report.

## From an agent, skip the curl

If Claude Code or Cursor is the thing running `quarto render`, use
Comma's MCP server instead of shell plumbing. The same `comma_sk_…` token
gates both surfaces, and the agent gets typed tools: `create_report`,
`update_report`, `list_comments`, `reply_to_comment`. The end of an
agentic task becomes "render the qmd, publish to Comma, return the share
link" — and the start of the next one becomes "read the open comments and
address them." See [Use Comma with Claude Code](/mcp/claude-code) for the
one-line plugin install.

## What renders, honestly

Comma renders your HTML untouched inside an opaque-origin sandbox — it
does not reformat or restyle Quarto's output. One exception, by design:
the API strips `<script>` tags and inline event handlers before storage,
as defense-in-depth on a write surface that accepts arbitrary HTML.

In practice:

- **Survives faithfully:** all text and markdown output, tables
  (including pandas/gt styling), CSS themes, static figures
  (matplotlib/ggplot as SVG or PNG), embedded images, code listings with
  highlighting.
- **Degrades:** anything that needs JavaScript at view time — Plotly and
  Bokeh interactivity, OJS cells, tabsets, collapsible code blocks.

For a document that exists to be reviewed, static figures are usually the
right call anyway: a reviewer can anchor a comment to a specific rendered
chart, which they can't do to a tooltip. If the analysis needs live
exploration, publish the static report to Comma and link the interactive
app from within it.

## Scheduling the render

Two ways to make this recur:

- **Your scheduler, Comma as destination.** A cron job or CI workflow
  runs `quarto render` and the PATCH call above. Works on every Comma
  plan, including Free.
- **Comma routines.** Comma's hosted cron re-runs a skill and republishes
  the report — at any cadence on every plan, with prepaid cost caps. You pay
  only for the AI compute (bring your own AWS Bedrock key for free, or draw
  down prepaid credits). Right when you'd rather not own the scheduler, the
  credential storage, and the machine that stays awake. See
  [routines](/features/routines).

Either way reviewers experience the same thing: one bookmarked link that
refreshes on cadence, with their comments carried across runs.

## Try it

Publishing, collaboration, and scheduled routines are all free — you pay
only for the AI compute a routine uses (bring your own AWS Bedrock key for
free, or draw down prepaid credits). Render something you already have and
see how review feels when the comment sits on the table cell it's about.

**[Create your first report →](https://commareports.com/)**

### Related

- [Use Comma with marimo](/with/marimo) — the notebook-export pipeline
- [Use Comma with Jupyter](/with/jupyter) — the nbconvert pipeline
- [Datapane alternative](/alternatives/datapane-alternative) — where one-line publishing went
- [Use Comma with Claude Code](/mcp/claude-code) — the MCP route
