How this site is built

/ Article

This is the first post, so it may as well explain the machine that published it. The whole site is static files — there is no server, no database, and nothing to keep running.

Writing a post

Drop a markdown file into src/content/blog/en/. The filename becomes the URL, so how-i-removed-greptile.md publishes at /blog/how-i-removed-greptile. The frontmatter is short:

---
title: How I removed Greptile
description: One sentence for search results and social cards.
pubDate: 2026-08-07
tags: [tooling, code-review]
---

Set draft: true while you’re still working on it. Drafts render in npm run dev but are left out of the build.

Translation

When a post lands on main, a GitHub Action sends it to DeepSeek V4 Flash and writes eight translations back into the repo as ordinary markdown files. The slug gets translated too, so the Turkish version of this post lives at a Turkish URL rather than an English one bolted onto a /tr prefix.

Each translated file records a hash of the English source it came from. On the next run, posts whose hash still matches are skipped — so editing one post re-translates one post, not the whole archive.

Layer Choice
Framework Astro, static output
Hosting Cloudflare Workers static assets
Translation DeepSeek V4 Flash on Fireworks
Content Markdown in git

Deployment

Merging to main runs the translation pass, commits whatever changed, builds, and deploys. The build is a few seconds and the output is a folder of HTML.

The nicest property of a static site is that the failure modes are boring. Nothing can fall over at 3am, because there is nothing running.

Press T to flip between light and dark, and B, A, G or L to jump around the site.