tiennm99 d0f617d919 fix(ci): correct subpath URL emit + build into public/tsuki for htmltest
Run 25919953710 still failed htmltest on both Hugo legs. Two distinct
issues, both pre-existing latent bugs that v0.3.0 made impossible to
ignore:

1. Several theme templates piped paths with a leading slash through
   `relURL`, which in Hugo means "this is already absolute — leave it
   alone." The intended subpath prefix (`/tsuki/`) was therefore never
   added, producing hrefs like `href="/search/"` and `href="/"`. In
   production the GitHub Pages mount masked this (broken links from
   the page's perspective still happened to resolve under the repo
   path most of the time), but htmltest correctly reported them as
   broken. Fix by either:
   - using `site.Home.RelPermalink` for the home link, or
   - piping a string without a leading slash through `relLangURL`
     (so Hugo prepends the baseURL path), or
   - stripping the leading slash from data-driven URLs first via
     `strings.TrimPrefix "/"` and then `relLangURL`.

   Affected: header.html, search-button.html, recent-posts.html,
   home/hero.html, nav.html, 404.html, search/list.html (Pagefind UI
   asset URLs).

2. htmltest has no URL-rewriting feature (the `URLSwap` config in the
   prior `d30f50f` "fix" was never read by htmltest — confirmed by
   reading htmltest 0.17.0 source). The only clean way to make
   internal-link checking work with a `/repo/`-style baseURL is to
   mirror the URL structure on disk. CI now builds with
   `hugo --destination public/tsuki`, runs Pagefind/smoke/htmltest
   against that path, and uploads `exampleSite/public/tsuki/` as the
   Pages artifact. The artifact contents become the served site
   under `/tsuki/`, identical to the prior behaviour from the
   browser's point of view. `.htmltest.yml` drops the dead URLSwap
   block.

Also: `tmp/` (htmltest's runtime cache) added to .gitignore so local
runs don't dirty the working tree.

Local verification: 32 smoke checks green; htmltest reports
`✔✔✔ passed, tested 29 documents` against the subpath build.
2026-05-15 20:31:00 +07:00
2026-05-07 20:27:07 +07:00
2026-05-07 20:27:07 +07:00
2026-05-07 20:25:16 +07:00
2026-05-07 20:27:07 +07:00

tsuki (月)

build license Hugo CSS a11y

A Hugo blog + personal portfolio theme. The homepage is the portfolio — bio, featured projects, recent posts. Posts live at /post/. Vietnamese-first typography, View Transitions on navigation, Pagefind search, Giscus comments.

月 (tsuki): the moon. Quiet, observed, returned to. Companion to bonsai in the same naming family.

Live demo

Status

v0.1.0 — initial release. See CHANGELOG.md.

Features

  • Blog — posts, tags, categories, year-grouped archive, paginated post list
  • Personal portfolio on the homepage — driven by data/profile.yaml + data/projects.yaml, no separate /portfolio section
  • SearchPagefind, zero-runtime, indexed at build time
  • CommentsGiscus (GitHub Discussions)
  • Vietnamese-first — diacritic-safe typography, native vi date formats, ASCII heading IDs
  • Dark modeprefers-color-scheme + persistent toggle, no flash of wrong theme
  • View Transitions API — smooth same-document navigation in supporting browsers
  • Table of contents — auto-mounted on long posts, sticky on wide viewports, IntersectionObserver active highlight
  • No build step — pure Hugo + browser ES modules. No SCSS, no TypeScript, no bundler in the theme
  • Light — CSS ≤ 4 KB gz, JS ≤ 1 KB gz (excluding Pagefind UI)

Quick start

git submodule add https://github.com/tiennm99/tsuki.git themes/tsuki
echo 'theme: tsuki' >> hugo.yaml

Full installation guide (submodule, Hugo Module, Pagefind setup, required site config): docs/installation.md.

exampleSite/hugo.yaml is a complete working example.

Documentation

Search and comments

Search uses Pagefind, built post-Hugo via npx pagefind --site public. tsuki pins Pagefind in its own package.json for submodule consumers; Hugo Module consumers install Pagefind in their own site (see docs/installation.md). No runtime dependency.

Comments use Giscus. Generate config at giscus.app and add to params.comments.giscus.* to enable. Defaults to off.

Browser support

Modern evergreen browsers. View Transitions and :has() are progressive enhancements; the theme remains functional without them.

License

Apache-2.0

S
Description
月 — Hugo blog + personal portfolio theme. Vietnamese-first typography, View Transitions API, Pagefind search, Giscus comments. Companion to bonsai.
Readme Apache-2.0 549 KiB
Languages
HTML 47.6%
CSS 36.7%
Shell 9.9%
JavaScript 5.8%