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:
format:
html:
embed-resources: true
Then:
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:
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:
{
"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:
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 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 renderand 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 — daily on Pro ($9/month), hourly on Team. Right when you'd rather not own the scheduler, the credential storage, and the machine that stays awake. See routines.
Either way reviewers experience the same thing: one bookmarked link that refreshes on cadence, with their comments carried across runs.
Try it
Publishing and collaboration are free — only creators pay, and only for scheduling and team features. Render something you already have and see how review feels when the comment sits on the table cell it's about.
Related
- Use Comma with marimo — the notebook-export pipeline
- Datapane alternative — where one-line publishing went
- Use Comma with Claude Code — the MCP route