I built this site in an afternoon. Astro for the frontend, Cloudflare Workers (with static assets) for hosting, GitHub for the repo, domain bought through Cloudflare Registrar so DNS just worked. A few things I’d tell myself the day before.
Cloudflare merged Pages into Workers
If you read a guide that says “use Cloudflare Pages,” the UI may not have a Pages tab anymore — it’s been folded into Workers. The static-site flow still works, but you need a small wrangler.jsonc in the repo:
{
"name": "my-site",
"compatibility_date": "2025-01-01",
"assets": { "directory": "./dist" }
}
Then in the Cloudflare UI: build command npm run build, deploy command npx wrangler deploy. Same end result, slightly different path.
Astro pages with full HTML need external CSS
I burned twenty minutes on a CSS bug that wasn’t a CSS bug. If your Astro .astro page contains a full <html> document (rather than using a Layout), inline <style> blocks can get stripped or fail to apply. Move the CSS to its own file and import it from the page’s frontmatter:
---
import '../styles/global.css';
---
Annoying, undocumented in the place I was looking, two-second fix once you know.
Content collections are worth it on day one
Astro’s content collections felt like overkill for a single post. They aren’t. The setup is small (src/content.config.ts, a folder per section, a dynamic [...slug].astro route) and the payoff is large: every future post is just a markdown file with frontmatter. No code changes to publish.
The actual lesson
The shape of the work was: pick a stack, scaffold, hit a wall, push through, ship. About three hours from “I own a domain” to “the site is live.” The thing that made it fast wasn’t the tools — it was committing to ship the skeleton first, then iterate.
Polished homepages don’t ship. Skeletons do.