skip to content
Astro Cactus
Table of Contents

I’ve been meaning to put together a personal site for a while — somewhere to write about the things I’m working on, break down technical problems I’ve run into, and generally have a place on the internet that’s mine. This post is about how I built it.

The Stack

The site is built on Astro — a framework that ships zero JavaScript by default and lets you write content in Markdown or MDX. For a blog, that’s exactly what you want: fast static pages, great SEO, and no overhead.

For the theme I went with Astro Cactus, a community theme that comes loaded with things I didn’t want to wire up from scratch:

  • Dark/light mode toggle
  • Full-text search via Pagefind
  • Automatic Open Graph image generation
  • RSS feed
  • Table of contents on long posts
  • Syntax-highlighted code blocks via Expressive Code

Hosting is on Cloudflare Pages — free tier, global edge deployment, and automatic deploys on every push to main.

Project Setup

Getting started was straightforward:

Terminal window
npm create astro@latest -- --template chrismwilliams/astro-theme-cactus
git init && git remote add origin <your-repo>
git push -u origin main

One thing to watch: the Cactus theme is a pnpm project. If you run npm install locally, you’ll end up with both a package-lock.json and a pnpm-lock.yaml in the repo. Cloudflare Pages will detect the pnpm-lock.yaml and run pnpm install, which works — but having both lockfiles around is messy. Delete package-lock.json and standardize on pnpm.

Writing Posts

Content lives in src/content/post/. Each post is a Markdown or MDX file with frontmatter:

---
title: My Post Title
description: A short description for SEO and previews
publishDate: 2026-06-23
tags: [astro, web-dev]
---
Your content here.

For posts with embedded video, I use MDX and a thin wrapper around @astro-community/astro-embed-youtube:

import YouTube from "@/components/YouTube.astro";
<YouTube id="dQw4w9WgXcQ" title="Never Gonna Give You Up" />

Which renders like this:

Play

Deploying to Cloudflare Pages

Connecting Cloudflare Pages to GitHub took about 5 minutes:

  1. Workers & PagesCreate applicationPagesConnect to Git
  2. Select your repo
  3. Set the build config:
    • Framework preset: Astro
    • Build command: npm run build
    • Output directory: dist

After the first successful build, every push to main triggers an automatic deployment to Cloudflare’s edge network. Build times are typically under 60 seconds.

What’s Next

The scaffolding is done. Next up: actual content. I’ll be writing about the things I’m building, breaking down problems I’ve solved, and documenting decisions along the way.

If you’re thinking about building something similar, Astro + Cloudflare Pages is a genuinely great combo — fast, free, and low maintenance.