Versioned previews

Browse the docs at any branch, commit or pull request through /tree, /blob and /pr URLs, without touching production.

Because content is addressed by commit, the site can render any version of your docs on demand. Prefix a URL and you're browsing another branch, commit or pull request — no build, no deploy, no separate preview environment.

ModeURL patternContent
Branch/tree/:branch/<page>Latest content commit on the branch (follows new pushes)
Commit/blob/:sha/<page>That exact commit, immutable
Pull request/pr/:number/<page>The PR's head commit (follows new pushes)

For example, this very page on the main branch lives at /tree/main/concepts/versioned-previews.

How it works

A preview isn't a filtered view of production — it's a full content instance built from that version's files. The navigation tree, search index, and every internal link are rebuilt from the previewed commit and prefixed with the version base, so you browse a coherent snapshot. A page that only exists on your branch is fully navigable there.

Branch previews resolve the branch to its latest content commit on request, so refreshing a /tree/ URL after a push shows the new content. Commit previews are immutable and cached accordingly. Pull request previews resolve the PR to its head commit on request, so they follow new pushes like branch previews do — including pushes to a fork branch.

Fork pull requests

GitHub shares git objects across the fork network: once a fork opens a pull request, its commits become fetchable through your repository's API. Rendering any well-formed SHA would let anyone put arbitrary markdown on your domain by opening a PR from a fork — a phishing vector, even with scripts and embeds stripped.

So a commit only renders under /blob/:sha when at least one of these holds:

  • The commit is in the production branch's history (this keeps version-history links working).
  • A pull request from your own repository contains it. Contributors with push access could publish a /tree/ preview anyway, so their PRs need no extra step.
  • A pull request from a fork contains it and a maintainer added the preview:enabled label to that PR.

/pr/:number follows the same rule: same-repo PRs always render, fork PRs only with the preview:enabled label. Removing the label revokes both within about a minute (the decision cache's TTL).

Every other SHA answers 404, and /tree/ rejects GitHub's hidden pull/<n>/head refs, so the label check can't be sidestepped through a branch preview.

What previews are for

  • Reviewing content PRs — share a /pr/123 or /tree/my-branch link instead of asking reviewers to run the site. Pair it with the PR preview comment action to get links posted automatically.
  • Checking history — the version history panel (keyboard shortcut g then h, on any docs page) lists the commits that touched the current page and links each one to its /blob/ preview.
  • Debugging — pin a report to an exact commit with an immutable /blob/<sha> URL.

Good to know

  • Previews are public, like the rest of the site, but send noindex robots headers and canonicalize to the production URL — they won't compete with your real pages in search.
  • The raw Markdown mirrors cover production pages only — preview pages serve HTML.
  • "Edit this page on GitHub" targets the previewed branch on /tree/ pages, and is disabled on /blob/ and /pr/ pages — a commit can't be edited, and a PR may come from a fork branch the site can't link an editor to.
  • Preview instances are kept in a small LRU pool per server instance; evicted versions rebuild on demand, and their parsed pages survive in the per-SHA cache.