Skip to content

Hugo docs site: buildable and previewable locally (GH-91) - #98

Merged
Ilyes512 merged 3 commits into
mainfrom
docs/GH-91-hugo-site-local
Aug 16, 2026
Merged

Ilyes512 merged 3 commits into
mainfrom
docs/GH-91-hugo-site-local

Conversation

@Ilyes512

@Ilyes512 Ilyes512 commented Aug 12, 2026 •

Copy link
Copy Markdown
Member

Summary

First of two stacked PRs for #91. This one makes docs/ a real Hugo site that builds and previews
locally; the follow-up deploys it to GitHub Pages at https://labelsync.specs.dev/ (workflow, Pages
settings, DNS).

  • Site scaffolding mirroring specsnl/specs-cli:
    docs/hugo.toml (Hextra as a Hugo module, baseURL already pointed at the production domain),
    docs/go.mod/go.sum as a module of their own, .gitignore, nginx.conf, the three ported
    partials, the landing page, and docs/content/docs/_index.md — the file whose absence meant
    nothing rendered at all.
  • Local build through Task: hugo and docs-preview services under a docs profile, and
    docs:build / docs:serve / docs:preview / docs:mod:tidy. Everything through Docker; no
    local Hugo or Go needed.
  • All 104 in-content .md links converted to {{< ref >}}, which resolves against the content
    file and fails the build when a target moves. They 404 on the built site as written, and
    task md:check has nothing to say about it.
  • AGENTS.md gains the four commands and the link convention, and the root .gitignore gains
    .playwright-mcp — the scratch directory the browser-driven link crawl leaves behind.

Decisions

  • Logo: the specs mark reused as-is, favicons included. labelsync sits next to specs-cli under
    the same domain and brand; a mark of its own is design work this issue does not need to invent.
  • {{< ref >}} over extensionless links. Extensionless refs resolve against the page URL, so
    ../usage/commands from /docs/architecture/plan/ silently lands on
    /docs/architecture/usage/commands. ref keeps the on-disk path and is verified at build time.
  • locale instead of the languageCode specs-cli still uses — deprecated in Hugo 0.158.

Verification

  • task docs:build clean; the only warnings left come from Hextra's own templates.
  • task docs:preview and task docs:serve both render from this checkout: sidebar, search index,
    dark-mode toggle, TOC, hero and the six feature cards.
  • Crawled every internal href of the built site over the nginx preview — 52 unique URLs, no 404s.
  • task checkall green, re-run after rebasing onto main at 3d05e56.

Not in this PR (second one in the stack)

.github/workflows/docs.yml, enabling Pages, the custom domain and HTTPS, and repointing the
labelsync.specs.dev CNAME at specsnl.github.io. Those boxes on #91 stay unticked here, so this
PR does not close the issue.

@Ilyes512
Ilyes512 force-pushed the docs/GH-91-hugo-site-local branch 2 times, most recently from da82511 to f53907e Compare August 16, 2026 20:32
docs/content/ has carried Hugo frontmatter since it was written, but nothing
rendered it: no hugo.toml, no theme, no layouts. This adds the site around the
pages that are already there, mirroring specsnl/specs-cli so the two documentation
sites stay one arrangement rather than two.

- hugo.toml points baseURL at https://labelsync.specs.dev/ and imports Hextra as
  a Hugo module. `locale` rather than the `languageCode` specs-cli still uses,
  which Hugo 0.158 deprecated.
- docs/go.mod is a module of its own, so the root `go mod tidy -diff` that
  `task tidy:check` runs never sees the theme.
- content/docs/_index.md is what was missing for anything to render at all: it
  carries the `cascade: { type: docs }` that gives every page below it the
  sidebar layout.
- content/_index.md is the landing page — hero, buttons, and a feature grid.
- The layouts are the three partials specs-cli overrides: the specs.nl footer,
  the brand primary colour with the sticky footer and stable content width, and
  the card shortcode.
- The logo and favicons are the specs mark reused as-is. labelsync is a specs
  tool sitting next to specs-cli under the same domain, and a mark of its own is
  design work this issue does not need to invent.
Two services under a `docs` profile, per the Taskfile-only policy: the pinned
hugomods image sharing the Go caches with the other services, and nginx serving
the built docs/public/ — a preview of exactly what Pages will get.

`docs:serve` is the live-reload dev server; `docs:preview` rebuilds with the
localhost baseURL first, because `{{< ref >}}` renders absolute URLs off baseURL
and would otherwise send every in-page link to the production domain.

docs-preview is the one service that keeps the image's default user: nginx binds
port 80 and writes its pid as root, then drops to its own unprivileged worker.
Every relative link in docs/content/ was written as `./output.md` or
`../usage/commands.md#prune`. Hugo does not rewrite `.md` links and Hextra ships
no render-link hook, so all 104 of them 404 on the built site while
`task md:check` stays green — the check has nothing to say about a link that
resolves on github.com and nowhere else.

`{{< ref >}}` takes the path unchanged, so the diff is mechanical, and it
resolves against the content file rather than the page URL — which the
extensionless form does not: `../usage/commands` from `/docs/architecture/plan/`
lands on `/docs/architecture/usage/commands`, and nothing reports it. A ref that
cannot be resolved fails the build instead.

The github.com links to design.md stay absolute; that file is deliberately not
part of the site.

Verified by crawling every internal href of the built site over the nginx
preview: 52 unique URLs, no 404s.
@Ilyes512
Ilyes512 force-pushed the docs/GH-91-hugo-site-local branch from f53907e to 74227a8 Compare August 16, 2026 20:34
@Ilyes512
Ilyes512 merged commit 5181d38 into main Aug 16, 2026
5 checks passed
@Ilyes512
Ilyes512 deleted the docs/GH-91-hugo-site-local branch August 16, 2026 20:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant