A static GitHub Pages site that hosts a growing collection of standalone HTML pages, presented as a searchable, filterable, tag-grouped card grid.
- Index UI — React + Vite, with fuzzy search (Fuse.js), multi-select tag filtering, a "group by tag" view, and a dark/light theme toggle.
- Content — raw
.htmlfiles live inpublic/pages/and are copied into the build untouched (never bundled). - Indexer —
build_index.pyreads each file's<title>and<meta>tags and regeneratespublic/posts.json. - Deploy — pushing to
maintriggers GitHub Actions, which re-indexes, builds, and publishes to Pages.
Live site (after first deploy): https://hopezh.github.io/oat_garden_v01/
npm install
npm run dev # predev re-runs build_index.py, then starts ViteThe base in vite.config.js is /oat_garden_v01/ so assets resolve under the
repo subpath. All fetches/links use import.meta.env.BASE_URL.
-
Drop a self-contained
.htmlfile intopublic/pages/. Give it a<title>and these<meta>tags so it indexes well:<title>My Page Title</title> <meta name="description" content="One-sentence summary."> <meta name="keywords" content="tag-one, tag-two, tag-three"> <meta name="date" content="2026-06-01">
(No date → the file's modification time is used. No title → the filename.)
-
(Optional)
npm run devto preview — re-indexing happens automatically. -
Commit
public/pages/<file>.htmlandpublic/posts.json, thengit push.
The push triggers the workflow; the new card appears on the live site within a minute or two.
If you'd rather not hand-write the <meta> tags, run the /enrich-pages
slash command in
Claude Code from the project root:
/enrich-pages all
It scans every .html file in public/pages/, and for any page missing a
description, keywords, or date <meta> tag, it reads the page content,
generates sensible values, and inserts the tags in place. The all argument
processes the whole folder; omit it to enrich only pages added or changed since
the last run. When it finishes, it re-runs build_index.py so public/posts.json
reflects the new metadata. Review the edits, then commit and push as usual.
.github/workflows/deploy.yml # CI: re-index, build, deploy to Pages
public/
pages/ # standalone .html files
posts.json # generated by build_index.py
src/
App.jsx # fetch + search + filter + theme state
components/ # SearchBar, TagFilter, PostCard, CardGrid, ThemeToggle
hooks/useTheme.js # data-theme on <html>, persisted to localStorage
theme.css # Fraunces + teal design tokens (light/dark)
build_index.py # the indexer (stdlib only)
vite.config.js # base: '/oat_garden_v01/'