Papa Labs

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 .md file — drop it into src/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 homepage

astro.build — “The web framework for content-driven websites,” which is exactly what a blog is

Here’s the result (dark mode):

Papa Labs homepage in 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

  1. Create my-post.md in src/content/posts/ (the filename becomes the URL);
  2. 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
---
  1. npm run dev for local preview (http://localhost:4321), auto-reload on save;
  2. When done, remove draft and run npm run build once (this also regenerates the search index).

Where each feature lives

FeatureImplementation
Full-text searchPagefind; index generated at build time
Dark modelocalStorage + 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.

← All posts