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.