Wie dieser Blog gebaut ist

  • Philipp
  • 3 Min. Lesezeit
Schematischer Aufbau einer statischen Website

Der erste Beitrag handelt vom Blog selbst. Kurzfassung: Es gibt keine Datenbank, kein CMS und keinen Server, der zur Laufzeit etwas rendert. Ein Beitrag ist eine Datei im Repository, und npm run build macht fertiges HTML daraus.

Warum Astro

Das Layout stammt aus einem Next.js-Theme. Für einen Blog, der aus Text und ein paar Bildern besteht, ist React zur Laufzeit aber viel Gepäck für wenig Nutzen. Astro rendert alles beim Bauen und liefert von sich aus kein JavaScript aus. Nur dort, wo ein Skript wirklich gebraucht wird (sticky Header, mobiles Menü, back-to-top), kommt ein kleines Inline-Skript dazu. Auf der Startseite sind das zusammen rund 2,4 KB.

Ein Beitrag ist eine Datei

Alle Beiträge liegen in einem Verzeichnis. Der Dateiname wird zur URL: wie-dieser-blog-gebaut-ist.mdx ergibt /beitraege/wie-dieser-blog-gebaut-ist/. Oben steht das Frontmatter, darunter Markdown. Und weil es MDX ist, bei Bedarf eigene Komponenten wie die Hinweisbox weiter oben.

---
title: "Wie dieser Blog gebaut ist"
description: "Astro, MDX und ein Ordner voller Dateien."
pubDate: 2026-09-14
category: "Softwareentwicklung"
tags: ["Astro", "MDX"]
cover: "../../assets/blog/astro-setup.png"
---

import { Callout } from "../../components/content";

Normaler Markdown-Text.

<Callout type="tip">Und dazwischen eine Hinweisbox.</Callout>

Das Frontmatter ist keine lose Vereinbarung, sondern ein Schema. Astro nennt das Content Collections1 und prüft die Felder beim Build mit Zod. Ein Tippfehler im Feldnamen oder ein fehlendes Titelbild bricht den Build ab, statt still eine kaputte Seite zu erzeugen.

// src/content.config.ts
const blog = defineCollection({
  loader: glob({ base: "./src/content/blog", pattern: "**/*.{md,mdx}" }),
  schema: ({ image }) =>
    z.object({
      title: z.string().max(120),
      description: z.string().max(320),
      pubDate: z.coerce.date(),
      category: z.string(),
      tags: z.array(z.string()).default([]),
      cover: image(),
      draft: z.boolean().default(false),
    }),
});

Aus dem Frontmatter entsteht mehr als der Beitrag selbst. Jede Kategorie und jedes Schlagwort bekommt automatisch eine eigene Übersichtsseite, ohne dass irgendwo etwas registriert werden muss.

Was beim Bauen passiert

npm run build erzeugt den Ordner dist/, und der ist alles, was auf dem Server liegt.

WasWie
SeitenEine index.html pro URL fertig gerendert
BilderAus src/assets/
SchriftWird selbst gehostet
IconsFont-Awesome-CSS auf die genutzten Icons reduziert: 532 KB → 19 KB
SuchindexPagefind läuft nach dem Build über dist/ und legt den Index daneben
RSS, SitemapAus denselben Daten wie die Seiten

Zur Laufzeit passiert dann nichts mehr. Keine Cookies, kein localStorage, kein Analytics. Die Datenschutzerklärung ist daher entsprechend kurz.

Suche ohne Server

Die Volltextsuche läuft komplett im Browser. Pagefind2 zerlegt beim Build alle Beiträge in einen Index aus kleinen Fragmenten, von denen der Browser nur die lädt, die zum Suchbegriff passen. Indiziert wird nur, was im Beitragslayout entsprechend markiert ist.

Veröffentlichen

Ein Push auf den main-Branch reicht. GitHub Actions installiert die Abhängigkeiten, prüft Typen und Frontmatter, baut die Seite und deployed das Artefakt als Azure Static Web App.

Weil die Seite statisch ist, entscheidet sich alles beim Bauen. Ein Beitrag mit pubDate in der Zukunft wird nicht versteckt, sondern gar nicht erst gebaut und ist daher auch nirgens verfügbar.

// src/lib/posts.ts
export async function getPublishedPosts() {
  const now = Date.now();
  const posts = await getCollection(
    "blog",
    ({ data }) => import.meta.env.DEV || (!data.draft && data.pubDate.valueOf() <= now),
  );
  return posts.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
}

Fazit

Ein Blog braucht keinen Server. Ein Ordner mit Markdown-Dateien, eine Build-Pipeline und ein statisches Hosting reichen. Das Ergebnis ist schnell, günstig und wartungsarm. Wer einen Beitrag schreiben will, braucht nur einen Editor und git push.

Quellen

  1. Astro Docs – Content Collections

  2. Pagefind – Static low-bandwidth search

Teilen: