search: replace Fuse.js with Pagefind (Default UI) + full UI polish

Remove the legacy Fuse.js search from html-head.html (it double-loaded
with the new Pagefind UI; backup kept at html-head.html.bkup) and add a
Pagefind Default-UI partial (search.html) injected into the sidebar via
menu.html.

Index scoping: tag the article element with data-pagefind-body in
baseof.html, term.html, and posts/{single,list}.html so Pagefind indexes
page content only (pages without the tag are skipped; 404.html stays
untagged).

search.html (all overrides #search-scoped, since pagefind-ui.css loads in
<body> after the head CSS):
  - compact input/magnifier/clear-button fitted to the sidebar; clear
    button uses fixed px (not %) because the results drawer is an in-flow
    child of the form, which stretches the form to results height
  - hide the empty .result-thumb placeholder (no images in the index) that
    was pushing result text ~90px right
  - restyle matched-term <mark> from UA yellow to subdued slate
  - keyboard navigation (Pagefind 1.5.2 has none; stock Enter is a silent
    no-op): capture-phase keydown implements ArrowUp/Down highlighting with
    wraparound across top-level hits AND their nested sub-results (each sub
    highlights its own .result-nested row), Enter opens the highlighted
    result (or the top result), and a fingerprint-aware MutationObserver
    keeps the highlight across Pagefind's async re-renders without
    resetting it on every DOM patch
This commit is contained in:
noether
2026-10-11 08:59:18 -06:00
parent 2d8f79b7fd
commit 0d24df31ad
7 changed files with 241 additions and 12 deletions
@@ -32,13 +32,8 @@ https://github.com/alex-shpak/hugo-book
{{- $styles := resources.Get "book.scss" | resources.ExecuteAsTemplate "book.scss" . | css.Sass | resources.Minify | resources.Fingerprint }}
<link rel="stylesheet" href="{{ partial "docs/links/resource-precache" $styles }}" {{ template "integrity" $styles }}>
<!-- Search -->
{{- if default true .Site.Params.BookSearch -}}
{{- $searchJSFile := printf "%s.search.js" .Language.Lang }}
{{- $searchJS := resources.Get "search.js" | resources.ExecuteAsTemplate $searchJSFile . | resources.Minify | resources.Fingerprint }}
<script defer src="{{ "fuse.min.js" | relURL }}"></script>
<script defer src="{{ partial "docs/links/resource-precache" $searchJS }}" {{ template "integrity" $searchJS }}></script>
{{ end -}}
<!-- Search: handled by Pagefind (see _partials/docs/search.html, injected into the
sidebar via menu.html). The legacy Fuse.js search was removed to avoid double-loading. -->
<!-- Service Worker -->
{{- if .Site.Params.BookServiceWorker -}}