Repository navigation
Hugo docs site: buildable and previewable locally (GH-91) - #98
Merged
Merged
Conversation
Ilyes512
force-pushed
the
docs/GH-91-hugo-site-local
branch
2 times, most recently
from
August 16, 2026 20:32
da82511 to
f53907e
Compare
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
force-pushed
the
docs/GH-91-hugo-site-local
branch
from
August 16, 2026 20:34
f53907e to
74227a8
Compare
2 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
First of two stacked PRs for #91. This one makes
docs/a real Hugo site that builds and previewslocally; the follow-up deploys it to GitHub Pages at https://labelsync.specs.dev/ (workflow, Pages
settings, DNS).
specsnl/specs-cli:docs/hugo.toml(Hextra as a Hugo module,baseURLalready pointed at the production domain),docs/go.mod/go.sumas a module of their own,.gitignore,nginx.conf, the three portedpartials, the landing page, and
docs/content/docs/_index.md— the file whose absence meantnothing rendered at all.
hugoanddocs-previewservices under adocsprofile, anddocs:build/docs:serve/docs:preview/docs:mod:tidy. Everything through Docker; nolocal Hugo or Go needed.
.mdlinks converted to{{< ref >}}, which resolves against the contentfile and fails the build when a target moves. They 404 on the built site as written, and
task md:checkhas nothing to say about it.AGENTS.mdgains the four commands and the link convention, and the root.gitignoregains.playwright-mcp— the scratch directory the browser-driven link crawl leaves behind.Decisions
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/commandsfrom/docs/architecture/plan/silently lands on/docs/architecture/usage/commands.refkeeps the on-disk path and is verified at build time.localeinstead of thelanguageCodespecs-cli still uses — deprecated in Hugo 0.158.Verification
task docs:buildclean; the only warnings left come from Hextra's own templates.task docs:previewandtask docs:serveboth render from this checkout: sidebar, search index,dark-mode toggle, TOC, hero and the six feature cards.
hrefof the built site over the nginx preview — 52 unique URLs, no 404s.task checkallgreen, re-run after rebasing ontomainat 3d05e56.Not in this PR (second one in the stack)
.github/workflows/docs.yml, enabling Pages, the custom domain and HTTPS, and repointing thelabelsync.specs.devCNAME atspecsnl.github.io. Those boxes on #91 stay unticked here, so thisPR does not close the issue.