Background
This is the second version of my portfolio site, rebuilt from the ground up on Astro (v6) starting from Astro’s official portfolio starter template. The previous version ran on WordPress with a custom theme — moving to Astro let me drop the database and PHP runtime entirely in favor of a static site with a small amount of build-time data.
Content Collections
All of the work shown on this site — including this write-up — is managed through Astro’s content collections, defined in src/content.config.ts:
- A
workcollection loads Markdown files fromsrc/content/work, validated with a Zod schema covering title, description, publish date, hero image, an optional accentcolor, and a list of category references. - A
categoriescollection loads Markdown files fromsrc/content/categories, each typed as acontext,topic, ortool(e.g. “Astro,” “Web Development,” “WordPress”).
Each project’s categories are stored as references and resolved with getEntries(), so tags on a project page link out to a shared category page listing everything tagged with it.
Dynamic Routing
Individual project pages are generated by a single dynamic route, src/pages/work/[...slug].astro. Its getStaticPaths() function reads every entry from the work collection and statically pre-renders a page for each one, passing the entry as a prop. The page then:
- Renders the Markdown body with Astro’s
render()helper - Looks up and displays the project’s categories as linked pills
- Shows the hero image, title, and description from frontmatter
The same pattern powers src/pages/work/categories/[...slug].astro, which generates a page per category listing all related work.
Design System
- Theming: CSS custom properties drive a light/dark color scheme, toggled by a small custom element (
<theme-toggle>) that adds/removes atheme-darkclass on<html>and persists the choice. - Fonts: Typefaces are loaded through Astro’s built-in fonts API with the Fontsource provider — Public Sans for body text, Rubik for headings/branding, and Merriweather for serif accents.
- Components: Shared
.astrocomponents (Hero,Grid,Pill,Icon,PortfolioPreview,ContactCTA, etc.) keep layout and styling consistent across the home page, work archive, and individual project pages.
Build & Deployment
- The experimental Rust-based compiler (
experimental.rustCompiler) is enabled for faster builds. - The site deploys to Netlify via the
@astrojs/netlifyadapter.