Site architecture
Astro 7 static site, custom domain namanvashistha.com, hosted on GitHub Pages.
Pieces
Section titled “Pieces”| Thing | Where |
|---|---|
| Theme | package/src/ — local integration, exposes the spectre:globals virtual module (name, themeColor, OG defaults, giscus config) |
| Layout | src/layouts/Layout.astro — one layout, left/right slots via LayoutGrid |
| Search | Pagefind, indexed in postbuild, UI is hand-rolled in Navbar.astro (⌘K) |
| Comments | giscus, config injected from workflow env |
| Analytics | Umami, plus hits.sh view badges on blog posts |
| Docs | Starlight, at /docs — the one part with its own layout |
Collections
Section titled “Collections”src/content.config.ts. Markdown ones use glob(); the JSON ones use a
hand-written jsonListLoader that reads a single key out of a file.
posts,projects,microblog,about,docs— filestags,socials,workExperience,quickInfo— JSON, one key eachtagsis referenced by the others viareference('tags')
Why Starlight for /docs
Section titled “Why Starlight for /docs”A hand-rolled content collection reusing Layout.astro would have been ~4 files
and looked like the rest of the site. Starlight cost an Astro 6 → 7 upgrade, and
/docs looks different because it brings its own theme. Bought: a real docs
sidebar generated from folders, with no layout code to maintain.
Two things it broke on the way in — Expressive Code can’t also be its own
integration (config moved inside starlight({…})), and disable404Route is
required or Starlight’s 404 replaces ours.
Gotchas
Section titled “Gotchas”public/_headerssetsX-Robots-Tag: noindexon/*. That’s Cloudflare/Netlify syntax — GitHub Pages ignores it entirely, so it does nothing. Leftover.work.jsonis{"work": []}, so the build warns thatworkExperienceis empty on every run. Expected.src/content/other/doesn’t exist but is still declared as a collection — second warning on every build.