TL;DR
- Static site built with Astro 4 + Vue, posts written in Markdown
- Chose Astro because it ships zero JS by default and has built-in content collections
- Hosted on Cloudflare Pages — GitHub auto-deploy didn’t work out, deploying via Wrangler CLI script instead.
- Adding a post means creating a
.mdfile and runninggit push. That’s it!
Storyline
As recent interviews showed me, things I do as a hobby or in a homelab1 aren’t impactless — the problem is presenting them “the right way”. Unless I show something, it’s just my word.
I didn’t want to just create a GitHub account and dump my projects there. Instead, I want to show the story behind them: why I decided to build something, why I made certain decisions, and what impact those had. This blog (I hope) will let me do that.
After each post I’ll include a short note on whether AI was involved and, if so, to what extent — whether it just fixed some grammar, helped put things together, or wrote entire sections.
Why Astro
A devlog (or blog in general) is just a text. It doesn’t necessarily need a full frontend framework, a backend, or a database.2 What it needs is a fast, predictable way to turn an easy-to-write text format into HTML.
Astro does exactly that! By default it ships no JavaScript to the browser — pages are static HTML generated at build time. Vue is wired in as an integration for when something genuinely needs reactivity. Right now nothing does, but the option is there.
The other thing that sold it was content collections: a schema-validated layer on top of Markdown files. Define the shape of a post (title, date, description), and Astro enforces it at build time. No surprises at runtime, no missing frontmatter.
The alternative was something like Next.js, which would have been overkill, or a pure static site generator like Hugo, which felt like going in the wrong direction for a project that might eventually need some interactivity in the future.3
Deployment
Initially, I planned to connect Cloudflare Pages directly to GitHub for automatic deployments triggered by a push to main. However, setting up that seamless connection turned out to be more of a hassle than expected.
Instead of fighting the UI, I fell back to a Node.js deploy script using the Cloudflare Wrangler CLI. It builds the site locally, handles Git commits, and pushes the dist directory straight to Cloudflare.
(Originally written as a bash script, rewritten in Node.js for Windows compatibility.)
Here is the deploy.mjs script I’m currently using to chain things together:
import { execSync } from "child_process";
import { argv } from "process";
const msg =
argv.slice(2).join(" ") ||
`deploy: ${new Date().toISOString().slice(0, 16).replace("T", " ")}`;
function run(cmd) {
console.log(`\n▶ ${cmd}`);
execSync(cmd, { stdio: "inherit" });
}
run("npm run build");
run("git add .");
const hasChanges =
execSync("git diff --cached --name-only").toString().trim().length > 0;
if (hasChanges) {
run(`git commit -m "${msg}"`);
run("git push");
}
run("npx wrangler pages deploy dist --project-name=[REDACTED]");
The custom domain (blog.szabra.com) was one step in the Cloudflare Pages settings — add it as a custom domain, Cloudflare handles the DNS record and HTTPS certificate automatically.
Lessons learned
- Learning Astro was inspiring - gave me a great opportunity to use an elegant solution and experience its fantastic CLI.
- Connecting Cloudflare Pages to GitHub wasn’t an easy task - mitigated it by creating a deploy script for chaining things together - TODO: use a “proper deployment way”.
- Even at this early stage I caught myself wanting to over-engineer things.
AI Impact Disclaimer
- DEVELOPMENT: Guided code generation
- WRITING: Post scheme and grammar
Footnotes
-
Not really located at my home as the name suggests — just OVH bare metal and a few Mikrus VPSes. ↩
-
I’ve got experience with overengineering my projects - don’t want to make this mistake again. Delivering one piece at a time might be a desired approach. ↩
-
Yes, I’d love to add more features over time — I just need a valid reason first, otherwise I’ll overengineer it. ↩