Skip to content

Feature: client-side site search (Pagefind) - #62

Merged
rivassec merged 1 commit into
mainfrom
pagefind-search
Sep 11, 2026
Merged

rivassec merged 1 commit into
mainfrom
pagefind-search

Conversation

@rivassec

Copy link
Copy Markdown
Owner

Item 2, the last of the improvement list. Static, same-origin, CSP-clean search.

What

  • deploy.yml: after the Pelican build, npx --yes pagefind@1.5.2 --site output writes the UI assets and chunked index to output/pagefind/ (runner's preinstalled Node; version pinned). Placed before the csp_audit and lychee steps so both validate the search page.
  • /search/ shell page via TEMPLATE_PAGES: noindex, follow + excluded from the sitemap (search shells are thin content), self-canonical, with a noscript fallback pointing at Categories and the Guide. Search added to the menu.
  • CSP-clean by construction: the UI init lives in theme/js/search-init.js (no inline scripts - the csp_audit CI gate enforces this anyway), and every asset + index chunk fetches same-origin. When the Cloudflare security headers come back, script-src 'self'; connect-src 'self' works unchanged.
  • Drafts structurally cannot leak into search: indexing is scoped by data-pagefind-body, applied only to non-draft article bodies and non-hidden pages. With attribute scoping active, Pagefind ignores every page without it.

Verified locally (full deploy dress rehearsal)

  • Build + index: 23 pages indexed = exactly 21 published posts + About + Accessibility (drafts, tag pages, 404, and the search shell itself all excluded; one draft leaking would make it 24)
  • csp_audit: OK; canonical/noindex: 0 issues (search page noindex + out of sitemap); wellknown/llms + link-graph green; 27 tests pass
  • 876KB total index, chunks lazy-loaded per query

Note for reviewer

While testing this I confirmed the live site currently serves no security headers at all (no CSP/XFO) - the Cloudflare-dashboard headers from docs/security-headers.md have drifted. Separate from this PR (needs your Cloudflare access), but worth restoring; the site is CSP-ready per the csp_audit gate and this PR keeps it that way.

- deploy.yml gains a Pagefind index step after the build (pinned
  1.5.2, runner's preinstalled Node, output/pagefind/)
- /search/ shell page (TEMPLATE_PAGES): noindex + sitemap-excluded,
  self-canonical, Search menu item added
- zero inline scripts: UI init lives in theme/js/search-init.js, so
  the csp_audit gate and a script-src 'self' CSP both hold; all
  assets and index chunks fetch same-origin
- indexing scoped via data-pagefind-body on non-draft article bodies
  and non-hidden pages: 23 pages indexed = 21 posts + About +
  Accessibility; /drafts/ pages structurally cannot enter the index
@rivassec
rivassec merged commit 2203d93 into main Sep 11, 2026
17 checks passed
@rivassec
rivassec deleted the pagefind-search branch September 11, 2026 23:49
rivassec added a commit that referenced this pull request Sep 12, 2026
Search is Pagefind (/search/, PR #62). The tipue and stork branches
were guarded by PLUGINS entries that have never been set here, so the
assets (484KB) and their template hooks were dead weight - including
an inline onclick handler that only stayed out of csp_audit's sight
because its branch never rendered. Also removes the unused tipue
search.html results template.

Co-authored-by: rivassec <rivassec@rivassec.com>
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