Goal: Let visitors search across all WatchTheStars pages and posts (~300 pages: 108 blog posts + ~190 other pages).
Chosen approach: Pagefind — a static-site search library that indexes the built HTML at deploy time and runs entirely in the browser. No backend, no third-party account, no cost. Fits the existing Eleventy + Cloudflare Pages "build and push" workflow.
(This is a planning doc for review — it lives at the repo root and should not be deployed. Delete or move it once we've agreed the approach.)
| Option | Verdict |
|---|---|
| Pagefind | ✅ Auto-indexes built HTML, downloads index in small chunks per query, ships a themeable UI, zero backend/cost. Best fit. |
| Lunr.js / Fuse.js | ❌ Loads the whole index upfront; doesn't scale well past ~100 pages; hand-rolled indexing + UI. |
| Algolia DocSearch | ⚠️ Powerful + free tier, but adds an external account, a crawler to configure, and a dependency. Overkill here. |
| Cloudflare Worker + D1/Vectorize | ⚠️ Only worth it for true semantic search; real backend to build + maintain. Park as a future enhancement. |
Current chain (run by Cloudflare on every push to main):
npm run build → eleventy (renders _site/)
→ postbuild: node scripts/minify.mjs (PurgeCSS + clean-css + terser on _site/)
Pagefind runs last, after minify, so:
_site/pagefind/ after purge runs), so there's no risk of purging the search UI styles.New chain:
npm run build → eleventy
→ postbuild: node scripts/minify.mjs && npx pagefind --site _site
pagefind to devDependencies so Cloudflare installs it during npm install.postbuild script to append && npx pagefind --site _site.npx pagefind uses the locally installed binary).By default Pagefind indexes the whole <body>, which would pull in nav, footer, and the email signup widgets — noisy results. Fix by editing the shared layouts:
data-pagefind-body to the main content container in each layout (blog-post-enhanced.njk, planet-enhanced.njk, uap-feature.njk, and the base/homepage layout).data-pagefind-ignore to nav.njk, footer.njk, and the tonight-signup.njk widget so they're excluded everywhere.data-pagefind-meta="title" on the heading and an image meta tag, so results show a proper title + thumbnail.nav.njk (next to BLOG / UAP RESEARCH)./pagefind/pagefind-ui.js + CSS) opened in a modal/overlay.categorySlug (astronomy / uap) as a Pagefind filter so users can narrow results./search/ page for a full-page results view (in addition to the nav modal), useful for "no results" deep links.npm run build, then serve _site/ with the Python HTTP server and run real queries (e.g. "Jupiter", "Varginha", "meteor shower", a misspelling to confirm typo tolerance)._site/pagefind/ (expected: small — tens of KB downloaded per search, not the whole index).CLAUDE.md; Cloudflare rebuilds and the index regenerates on every deploy automatically./pagefind/, untouched by purge. Verify once after first deploy./pagefind/ folder is just assets.Roughly half a day end-to-end: ~1 hr wiring the build + dependency, ~1–2 hrs on layout data-pagefind-* attributes and the nav UI/styling, the rest on testing across page types. The optional v2 polish is separate.