ADR-004: Unify docs into a single Quarto website

Status 🟢 Accepted
Created 2026-07-04
Last Updated 2026-07-04
Deciders Novica Nakov

Update (see ADR-005): the site-unification decision below still stands, but the specific API-reference generation mechanism (quartify, create_book = FALSE / render_html = FALSE) described in Decision Outcome and Confirmation was replaced by ADR-005.

Context

quartify::rtoqmd_dir() converts roxygen comments in src/package_name/*.r into .qmd reference pages, but it has no concept of pages outside the R source tree it’s converting — it can’t include a README, an architecture overview, or ADRs. Left on its own, that leaves this project with two disconnected things: a generated API reference, and a pile of hand-written markdown (README.md, docs/architecture/index.md, docs/architecture/adr/*.md) with no shared navigation tying them into one site.

Problem Statement

How should this project combine hand-written docs (README, architecture, ADRs) and the quartify-generated API reference into one navigable, deployable documentation site?

Options Considered

Option Description Coherent nav Low maintenance No new tooling Keeps generated content out of src/ Overall score Notes
Weight - 2 1 1 2 - -
A. Disconnected pages Leave README/architecture/ADRs as loose markdown, quartify’s reference pages separate. ❌ ✅ ✅ ⚠️ 12 No unified site at all — status quo, not a real option.
B. Let quartify own the whole site (create_book = TRUE) quartify manages its own _quarto.yml/book project. ❌ ✅ ✅ ❌ 14 Confirmed via source: writes _quarto.yml into src/package_name/ and has no mechanism to include external pages — can never host the README/ADRs.
C. Hand-authored Quarto website rooted at docs/ quartify demoted to a flat .qmd emitter (create_book = FALSE, render_html = FALSE); its output is relocated into docs/reference/; a hand-authored docs/_quarto.yml ties README (via {{< include >}}), architecture/ADR markdown (rendered natively, no conversion needed), and the reference pages into one site. ✅ ⚠️ ✅ ✅ 20 Chosen. Quarto CLI is already a required/installed tool (used for docs today); no new dependency.
D. Drop quartify Hand-write all API docs, or adopt a different generator. ✅ ❌ ❌ ✅ 13 Throws away working roxygen→qmd conversion; pkgdown doesn’t work here either (no DESCRIPTION, see README’s Limitations section).

✅ = 3 (good), ⚠️ = 2 (acceptable), ❌ = 1 (poor)

Decision Outcome

We will use Option C. docs/_quarto.yml is a hand-authored Quarto website project that owns the site’s structure end to end: docs/index.qmd pulls in the root README.md (minus its GitHub-only badges block, see Consequences) via {{< include _readme.md >}} as the home page; docs/architecture/index.md and docs/architecture/adr/*.md are listed directly in the sidebar (Quarto renders plain .md natively, no conversion step); and docs/reference/*.qmd (quartify’s output, relocated there by just docs-build after generation) is listed as the API reference section. A single quarto render docs/ produces docs/html/, which is what generate-docs.yml deploys to GitHub Pages.

Consequences

  • Good, because there’s one deploy target (docs/html/) and one site combining everything, instead of disconnected pages.
  • Good, because src/package_name/ never accumulates generated .qmd/_quarto.yml artifacts — quartify’s output is immediately relocated out of the source tree.
  • Bad, because the “API Reference” sidebar section in docs/_quarto.yml needs one manual entry per added/removed source module — quartify gives no way to auto-discover this.
  • Unknown/risk: {{< include >}} splices markdown in literally, with no path rewriting — every repo-relative link in README had to be converted to an absolute GitHub URL so it resolves correctly both on GitHub and inside the transcluded docs page (done as part of this change). Same reasoning applies to README’s CI/release status badges — meaningful on GitHub, not on the docs site — so README wraps them in <!-- badges: start/end --> markers and docs-build strips that block into a generated docs/_readme.md that docs/index.qmd includes instead of README directly.

Confirmation

docs/_quarto.yml and docs/index.qmd are committed. docs/reference/, docs/_readme.md, and docs/html/ are gitignored (fully regenerated by just docs-build / CI every run). justfile’s docs-build recipe and .github/workflows/generate-docs.yml both run the same pipeline: generate + relocate quartify’s output, strip README’s badges block into docs/_readme.md, then quarto render docs/.