How this blog is built: Astro + Markdown architecture notes
This post is the site’s own manual: how it’s built, where things live, how articles get written. If I switch machines or forget the workflow, this page is enough.
Why Astro
The requirements were simple: articles are markdown, output is pure static, no database, no backend. Astro hits all of them:
- One article = one
.mdfile — drop it intosrc/content/posts/and it appears on the site; - The build output is plain HTML — deploying to Cloudflare Pages costs nothing;
- Code highlighting (Shiki), RSS and sitemap are built in or official plugins — no wheel-reinventing.

astro.build — “The web framework for content-driven websites,” which is exactly what a blog is
Here’s the result (dark mode):

This site’s homepage: hero, featured cards and post list, all generated from markdown and a few Astro components
Directory layout
papalabs-blog/
├── src/
│ ├── content/posts/ ← articles live here (markdown)
│ ├── layouts/Base.astro ← site shell: header, footer, dark mode
│ ├── pages/ ← routes: home, archive, tags, search, 404
│ ├── styles/global.css ← all styles, CSS variables for both themes
│ └── lib/ ← utilities, remark plugins
├── public/ ← static assets: logo, search index
└── astro.config.mjs
Daily writing workflow
- Create
my-post.mdinsrc/content/posts/(the filename becomes the URL); - Write the frontmatter:
---
title: Post title
date: 2026-07-05
tags: [networking, fortigate]
description: One-line summary for list pages and RSS.
draft: true # keep true until it's ready — won't appear on the site
---
npm run devfor local preview (http://localhost:4321), auto-reload on save;- When done, remove
draftand runnpm run buildonce (this also regenerates the search index).
Where each feature lives
| Feature | Implementation |
|---|---|
| Full-text search | Pagefind; index generated at build time |
| Dark mode | localStorage + prefers-color-scheme, CSS variable switch |
| Mindmap embeds | ```markmap code blocks, custom remark plugin + markmap |
| RSS / Sitemap | /rss.xml, /sitemap-index.xml |
Principle: all content is plain-text markdown under git. If I ever change theme, framework or even platform, the articles come along untouched.