Share ExDoc output

mix docs is one of the better documentation experiences in any ecosystem — module docs, @doc examples that are also tests, guides, a search box that works. It writes the whole thing to doc/ and then the ecosystem assumes the next step is publishing to Hex.

For an internal umbrella app, a client project, or a release candidate, that assumption is wrong in both directions: you do not want it public, and it is not a package.

Build it

MIX_ENV=docs mix docs
doc/
├── index.html
├── MyApp.Accounts.html      # one page per module
├── readme.html  changelog.html
├── dist/                    # js, css, the search index
└── assets/

Open index.html from the filesystem and the pages render but the search box does not: ExDoc fetches its index over XHR, which a browser blocks from a file:// origin. It is the same origin problem that breaks most generated docs when they are zipped and emailed.

Drop the folder in

Drag doc/ (or a zip of it) into Comma:

  • index.html becomes the report body — the page carrying the comment layer.
  • Module pages, guides, dist/ and assets/ upload alongside it, and relative references are rewritten to the uploaded copies, so search works and the sidebar navigates.
  • Scripts run inside a sandboxed iframe (allow-scripts, no allow-same-origin).

Access per report: private, your team, anyone signed in at your domain, or anyone with the link — see sharing & access control.

From CI

MIX_ENV=docs mix docs

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 doc/index.html \
        --arg t "MyApp — $(mix run -e 'IO.puts Mix.Project.config()[:version]')" \
        '{title: $t, html: $html}')"

Supporting pages go up through POST /api/v1/reports/$REPORT_ID/assets as base64 — one call per file, worth scripting once. See the API reference and publishing from CI.

An umbrella is the case that needs this most

An umbrella project generates docs per app, and the thing nobody has is a single readable view of the boundary between them — which context owns which schema, and which public function another app is allowed to call. Publishing each app's doc/ as its own report gives you that as a set of links, and comments anchored on a specific @doc are where the boundary argument actually belongs. See commenting on HTML.

Limits

  • Entry HTML: 5 MB. Assets: 25 MB per file, 250 MB and 500 files total. A large app with many modules can approach 500 pages — :filter_modules or splitting per umbrella app keeps it under.
  • Scripts run, sandboxed — no same-origin access.
  • 60 requests/minute per token.

Try it

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

Publish ExDoc output →

Related