# Share Go Package Docs — A Link, Not a localhost Port

Canonical: https://commareports.com/share-godoc
Published: 2026-09-14

> Go docs are a running server, not a file, so an internal module has no URL. Generate a static copy of pkgsite output and publish it to Comma — one link, private, with comments.

# Share Go package docs

Every other language's doc tool writes files. Go's serves them. `go doc` prints
to a terminal, `pkgsite -http=:8080` runs a web app, and pkg.go.dev indexes the
public module graph — which covers open source completely and internal code not
at all.

So the docs for the module five teams depend on exist only as a port on
somebody's laptop, and the actual documentation anyone reads is the source.

## Mirror pkgsite to static HTML

```bash
go install golang.org/x/pkgsite/cmd/pkgsite@latest
pkgsite -http=localhost:8080 ./... &

wget --mirror --convert-links --adjust-extension --page-requisites \
     --no-parent http://localhost:8080/github.com/acme/widgets
```

`--convert-links` is the load-bearing flag: it rewrites absolute links to
relative ones so the mirrored tree works detached from the server.
`--page-requisites` pulls the CSS and JS the pages reference.

The quick alternative, for one package and no styling:

```bash
{ echo '<!doctype html><meta charset="utf-8"><title>widgets</title><pre>'
  go doc -all ./widgets
  echo '</pre>'; } > widgets.html
```

Ugly, accurate, and one file.

## Publish the folder

Drag the mirrored directory (or a zip of it) into
[Comma](https://commareports.com/):

- The package index page becomes the **report body**.
- Subpackage pages, CSS and JS upload alongside it, with relative references
  rewritten to the uploaded copies, so cross-package links resolve.
- Scripts run inside a sandboxed iframe (`allow-scripts`, no
  `allow-same-origin`), so the outline sidebar and the expandable example
  blocks keep working.

Access is set per report — private, your team, anyone signed in at your domain,
or anyone with the link. An internal module's docs should be the second of
those, which is exactly the option pkg.go.dev does not have. See
[sharing & access control](/docs/sharing).

## From the release job

```bash
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 mirror/index.html \
        --arg t "widgets — $(git describe --tags)" '{title: $t, html: $html}')"
```

Supporting pages go up through `POST /api/v1/reports/$REPORT_ID/assets` as
base64. See the [API reference](/docs/api) and
[publishing from CI](/docs/ci).

PATCHing one saved id keeps a permanent URL whose content tracks the current
tag, and the revision history is an honest answer to "when
did that signature change?"

## Review the doc comments, not the diff

Doc comments get reviewed in the worst possible place: inline in a PR, where
the reviewer sees the comment and not the rendered page it becomes. Publishing
the rendered docs and commenting there — "this says what it does, not when it
returns an error" — puts the feedback where the reader's experience actually
is. Threads stay anchored across rebuilds. See
[commenting on HTML](/comment-on-html).

## Limits

- **Entry HTML: 5 MB.** Assets: 25 MB per file, **250 MB and 500 files total**.
  A mirror of a large module tree can pass 500 files — mirror the package
  subtree people actually consume, not the whole repo.
- **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 Go docs →](https://commareports.com/)**

### Related

- [Share a Go test report](/share-go-test-report) · [Share rustdoc](/share-rustdoc)
- [Share TypeDoc output](/share-typedoc) · [Share Sphinx docs](/share-sphinx-docs)
- [Share an HTML folder](/share-html-folder) · [Host an HTML file](/host-html-file)
