Anfang 2023 rief mich ein Medienverlag an. 14.000 Posts auf WordPress. Ein Theme, das über sechs Jahre hinweg vier verschiedene Entwickler zusammengestückelt hatten. Der Core Web Vitals Score war unterirdisch. Das LCP auf Mobile? 7,2 Sekunden. Sie hatten WP Rocket ausprobiert. Ein CDN? Auch das. Sogar die Hälfte ihrer Plugins rausgeworfen. Trotzdem blieb die Seite lahm. Das Problem war nicht WordPress selbst – es war die Architektur. Jedes Seiten-Rendering musste durch PHP, ein aufgeblähtes Theme und eine Datenbank-Abfragekette, die seit 2018 nicht angefasst worden war. Die Bottlenecks waren überall.
Wichtigste Erkenntnis: Headless WordPress mit Astro ist der optimale Ansatz für Content-Seiten: wp-admin für Redakteure, statisch-schnelles Frontend für Besucher und WPGraphQL als Schnittstelle zwischen beiden.
Das war der Moment, in dem ich mich wirklich auf ein Headless-Setup mit Astro als Frontend festgelegt habe. Nicht weil es trendig ist, sondern weil für eine Website mit Tausenden von Posts und umfangreichen redaktionellen Inhalten diese Architektur die einzige war, die Sinn machte.
Hier ist genau, wie ich es aufgebaut habe. Die Kompromisse, die echte Konfiguration, die Dinge, die mir Probleme bereitet haben.
---
Warum Astro und nicht Next.js
Diese Frage bekomme ich häufig gestellt. Next.js ist die offensichtliche Antwort, wenn du bereits ein React-starkes Team hast oder wenn du komplexe clientseitige Interaktivität brauchst. Aber für inhaltsreiche Websites? Astro gewinnt, und es ist nicht besonders knapp.
Astro liefert standardmäßig null JavaScript. Für einen Blog, eine Nachrichtensite oder ein Dokumentationsportal ist das die richtige Voreinstellung. Du aktivierst JavaScript dort, wo du es brauchst, statt dich aus einem 200-KB-React-Bundle auszutragen, den du größtenteils nicht willst. Die Astro-Docs zum Partial Hydration nennen es Islands-Architektur und erklären es besser als ich in einem Satz, aber die Kurzversion ist: Nur die interaktiven Teile bekommen JS. Der Artikeltext, der Header, die Seitenleiste? Statisches HTML.
Ich habe Ende 2022 eine juristische Content-Website mit Next.js und WordPress gebaut. Schnell genug, aber der Kunde fragte immer wieder, warum sein Lighthouse-Score auf Mobile 74 ist, wenn „es jetzt schnell sein soll". Hydration-Overhead. Mit Astro erreicht dieselbe Art von Website jetzt routinemäßig 95–98. Nicht prahlerisch, das ist einfach das, was dir die Architektur kostenlos gibt.
Wofür Astro nicht gut geeignet ist
Es lohnt sich, ehrlich zu sein. Wenn deine Website Echtzeit-Personalisierung, einen umfangreichen Warenkorb oder etwas braucht, das wirklich von clientseitigem State über viele Komponenten hinweg abhängt, fühlt sich Astro unbeholfen an. Es ist keine React-App. Das Islands-Pattern ist mächtig, aber es ist ein anderes mentales Modell als das Bauen von SPAs. Ich habe versucht, ein Client-Dashboard in ein Astro-Projekt zu zwingen, Mitte 2023, und bin innerhalb von zwei Wochen zu Next.js zurückgekehrt. Wisse, was du baust.
---
WordPress als Headless CMS einrichten
WordPress ist ein wirklich gutes Headless-Backend. Die WP REST API ist im Core enthalten, sie ist gut dokumentiert, und dein Editorial-Team muss nichts Neues lernen. Dieser letzte Punkt ist wichtiger, als Entwickler normalerweise zugeben.
Hier ist das Setup, das ich verwende:
- Installiere WordPress auf einer Subdomain, ich verwende cms.yourdomain.com oder api.yourdomain.com. Halte es hinter einer Basic-Auth oder beschränke zumindest den direkten öffentlichen Traffic. Das Frontend ist yourdomain.com. Zwei separate Deployments.
- Installiere das [WPGraphQL Plugin](https://www.wpgraphql.com/), ich bevorzuge GraphQL vor REST für Content-Sites, weil du deine Abfragen mit deinen Komponenten co-localisieren und genau die Felder abrufen kannst, die du brauchst. Kein Over-Fetching. Die REST API ist in Ordnung, aber sobald du 15+ benutzerdefinierte Felder pro Post-Type hast, ist der GraphQL-Ansatz deutlich sauberer.
- Installiere Advanced Custom Fields (ACF) und die WPGraphQL for ACF Extension. Diese Kombination macht WordPress wirklich flexibel als Headless-Content-Model – du kannst strukturierte Daten pro Post-Type definieren, sie durch GraphQL verfügbar machen und Astro konsumiert sie sauber.
- Deaktiviere Kommentare, Emojis und das Standard-XML-RPC, falls du das noch nicht getan hast. Diese fügen Overhead und Angriffsfläche hinzu, die du nicht brauchst.
- Stelle die Permalinks auf etwas Sinnvolles ein, bevor du anfängst zu bauen. Sie mitten im Projekt zu ändern, wenn deine Astro-Routes bereits gesetzt sind, ist echtes Ärger.
Eine Sache, bei der Menschen hängenbleiben: CORS. Standardmäßig erlaubt WordPress deinem Astro-Dev-Server (läuft auf localhost:4321) nicht, Requests an deine WP-Installation zu stellen. Füge das während der Entwicklung in die functions.php deines Themes oder ein kleines Utility-Plugin ein:
`` add_action('init', function() { header("Access-Control-Allow-Origin: *"); }); ``
Verschärfen Sie das auf spezifische Ursprünge in der Produktion. Offensichtlich.
---
Die Astro-Projektstruktur
Ich halte das durchdacht und konsistent über Projekte hinweg. Nach einem Dutzend oder so Headless-Builds ist das, was funktioniert:
`` src/ components/ layouts/ pages/ index.astro blog/ [slug].astro lib/ wpgraphql.ts ← alle WP-Abfragelog ik lebt hier styles/ ``
Die Datei lib/wpgraphql.ts ist der Ort, an dem ich jeden GraphQL-Fetch zentralisiere. Keine inline Fetch-Aufrufe, die über Page-Dateien verstreut sind. Jede Query ist eine benannte, exportierte Async-Funktion. Wenn du das über 14.000 Posts debuggen musst und etwas um 2 Uhr morgens kaputtgeht, wirst du dir selbst dankbar sein.
Beiträge zur Build-Zeit abrufen
Astros getStaticPaths ist hier deine Hauptstütze. Für einen Blog mit Tausenden von Beiträgen:
`` export async function getStaticPaths() { const posts = await getAllPostSlugs(); // ruft WPGraphQL auf return posts.map(post => ({ params: { slug: post.slug }, })); } ``
getAllPostSlugs paginiert durch WPGraphQL mit After-Cursorn – WordPress's GraphQL-Layer gibt standardmäßig 100 Posts pro Request zurück, also machst du für 14.000 Posts 140 Requests zur Build-Zeit. Das klingt beängstigend. In der Praxis läuft der vollständige Build auf einem anständigen Server in etwa 4–5 Minuten. Vollkommen akzeptabel für eine Website, die ein paar Mal pro Tag neu aufgebaut wird.
---
Bilder verwalten, ohne den Verstand zu verlieren
Das ist der Teil, über den niemand genug spricht. WordPress speichert Bild-URLs, die auf deine CMS-Subdomain verweisen. Wenn Astro statisch baut, leben diese Bilder immer noch auf cms.yourdomain.com, was bedeutet, dass deine Besucher Bilder von deinem WordPress-Server abrufen und möglicherweise dein CDN umgehen.
Ein paar Wege, wie ich das handhabe:
- Cloudflare vor beiden Domains. Die einfachste Option. Leite beide yourdomain.com und cms.yourdomain.com durch Cloudflare, konfiguriere aggressives Caching auf /wp-content/uploads/*, und es läuft meistens ohne Probleme.
- Verwende ein Media-Offload-Plugin. Mir gefällt WP Offload Media, es verschiebt Uploads zu S3 (oder kompatiblem Storage) und schreibt URLs automatisch um. Das ist der Ansatz, den ich für jede Site mit ernsthaftem Traffic nutze. Dein WordPress-Server serviert überhaupt keine Bilder mehr.
- Astro's Image-Komponente. Für Bilder, die du zur Build-Zeit kontrollierst (Featured Images, die via GraphQL abgerufen werden), kannst du die Remote-URL in Astro's <Image>-Komponente übergeben und sie optimiert, skaliert und serviert sie von deinem Build-Output. Funktioniert hervorragend. Funktioniert nicht für Bilder, die in Post-Body-HTML eingebettet sind – das erfordert einen anderen Ansatz.
Seahawk hatte letztes Jahr einen Travel-Content-Client mit etwa 8.000 Posts, extrem bilderlastig, durchschnittlich 12 Bilder pro Artikel. Ihr WordPress-Server wurde allein durch Bildanfragen gehämmert, selbst mit dem Headless-Setup. Der Umstieg auf S3 + CloudFront hat ihre Origin-Bandbreite um 94% reduziert. Wirklich transformativ für ihre Hosting-Rechnung.
---
Inkrementelle Builds und das Rebuild-Problem
Hier ist ein echtes Problem mit statischer Generierung im großen Maßstab: Dein Editor veröffentlicht eine Korrektur um 15 Uhr und muss dann 5 Minuten auf einen vollständigen Rebuild warten. Das ist in einer Newsroom nicht akzeptabel.
Ein paar Ansätze, die ich verwendet habe:
Option 1: Netlify oder Vercel mit On-Demand-ISR. Astro unterstützt Server-Side-Rendering mit Adaptern, du kannst Astro im Hybrid-Modus ausführen, wo die meisten Seiten statisch sind, aber spezifische Routen werden On-Demand gerendert. Für eine News-Site render ich oft die letzten 30 Tage von Posts statisch vor (hoher Traffic, braucht Speed) und setze ältere Archive-Seiten zum On-Demand-Rendering. Das Beste aus beiden Welten.
Option 2: Webhook-gesteuerte Partial Builds. WordPress feuert einen Webhook bei Post-Save ab (einfach mit dem WP Webhooks Plugin). Dieser Webhook trifft einen Netlify- oder Vercel-Deploy-Hook. Der Build läuft, er holt nur das, was sich geändert hat. Es ist nicht wirklich partial, Astro erstellt immer noch alles neu, aber wenn du deinen Build schnell hältst, sind 4 Minuten machbar.
Option 3: Nutze einfach SSR für das Ganze. Deploye Astro mit dem Node-Adapter auf einem VPS (ich nutze Hetzner dafür, billig, schnell, zuverlässig). Jede Seite rendert On-Request, du cachst aggressiv auf Nginx- oder Cloudflare-Ebene und hast sofortige Post-Updates. Das würde ich für eine richtige Publishing-Operation über 50.000 Posts tun.
Ehrlich gesagt? Die meisten Webseiten brauchen nicht die Komplexität von Option 1 oder 3. Ein 4-Minuten-Rebuild, der durch einen Webhook ausgelöst wird, ist für 90% der Content-Seiten in Ordnung.
---
Performance: Was du wirklich bekommst
Bei dem Publisher-Projekt aus der Einleitung, hier's, was nach der Astro-Migration passierte:
- LCP ist bei Mobile von 7,2s auf 1,1s gefallen (getestet mit WebPageTest von einem London-Node)
- Total Blocking Time sank von ~800ms auf 0ms (standardmäßig null JavaScript, denk dran)
- Der Google Search Console Core Web Vitals Report zeigte einen Anstieg von 3% auf 91% „Gut" bewerteter URLs in nur sechs Wochen nach dem Start.
- Die Hosting-Kosten sanken, weil der WordPress-Server keine Seiten mehr auslieferte, sondern nur noch API-Responses
Das ist keine Magie. Es passiert einfach, wenn man PHP-Rendering aus dem kritischen Pfad entfernt und einem Leser nicht mehr ein 400kb Theme JavaScript Bundle zusendet.
---
Die Bits, die dir Probleme bereiten werden
Ehrlich gesagt, Dinge, die ich auf echten Projekten debuggen musste:
- Entwürfe von Beiträgen in der Vorschau. Das ist in einem Headless-Setup wirklich nervig. WordPress' native Vorschau setzt auf Frontend-Rendering. Du brauchst einen Custom Preview Endpoint in Astro, der einen WordPress Preview Nonce akzeptiert und den Entwurf via WPGraphQL fetcht. Nicht schwer, aber es dauert einen Tag, um es richtig zu machen.
- Redirects. Wenn die alte Website hunderte Redirects in .htaccess hatte, leben die jetzt auf dem WordPress-Server. Du musst sie entweder in Astros Config replizieren oder WordPress erreichbar lassen und bestimmte Pfade proxyen. Ich habe beides gemacht. In Astro zu replizieren ist langfristig sauberer.
- Suche. WordPress' eingebaute Suche ist in einem Headless-Setup nutzlos. Ich nutze Algolia mit dem WP Search with Algolia Plugin. Indexiere deine Beiträge in WP, frage Algolia von einer Astro Island Component ab. Funktioniert gut.
- Menüs und Navigation. WordPress-Menüs sind irgendwie fummelig, um sie durch WPGraphQL freizulegen. Die wpgraphql-acf-Route endet oft sauberer, modelliere einfach dein Nav als ACF-Repeater und fertig.
---
FAQ
Brauche ich WPGraphQL oder kann ich einfach die REST API verwenden?
Du kannst die REST API absolut nutzen, sie ist in WordPress Core integriert und erfordert keine zusätzlichen Plugins. Für einfache Sites mit Standard-Posttypen und minimalen Custom Fields funktioniert das problemlos. GraphQL macht sich bezahlt, wenn du komplexe Content-Modelle mit vielen Custom Fields pro Typ hast. Die Möglichkeit, genau die Felder zu fetchen, die du brauchst, in einer einzigen Anfrage, ohne dich mit _embed-Parametern und verschachtelten REST-Calls herumzuschlagen, spart bei jeder Query Zeit. Die Entscheidung liegt bei dir. Ich finde GraphQL ab einer bestimmten Komplexitätsschwelle einfach sauberer.
Wie handhabe ich WordPress-Authentifizierung für Inhalte nur für Mitglieder?
JWT-Authentifizierung ist der Standard-Ansatz. Installiere das JWT Authentication for WP REST API Plugin, stelle Tokens bei Login aus, übergebe sie in deinen GraphQL-Request-Headern. Auf der Astro-Seite handhabst du das mit einer SSR-Route (nicht statisch), damit der benutzerspezifische Content pro Anfrage serverseitig gefetcht wird. Versuche nicht, das statisch zu machen, das führt zu Wahnsinn.
Ist das zu viel des Guten für einen kleinen Blog?
Ja, wahrscheinlich. Wenn du unter 500 Posts hast und einen Editor, lohnt sich der Aufwand zum Maintenainen eines Headless-Setups nicht. Nutze einfach ein gutes WordPress-Theme, optimiere deine Bilder, und mach dein Ding. Diese Architektur lohnt sich, wenn du Volumen, redaktionelle Komplexität oder Traffic-Level hast, wo Performance wirklich einen Unterschied beim Umsatz macht.
Wie sieht das Hosting-Setup in der Produktion aus?
WordPress (nur CMS) auf einem kleinen VPS oder managed WordPress Host, ich nutze Kinsta oder Cloudways. Astro-Frontend auf Vercel, Netlify oder einem Hetzner VPS mit Nginx je nach Projekt. Cloudflare davor. Die monatlichen Kosten für eine mittelgroße Content-Site liegen normalerweise zwischen 60–120 €, was oft weniger ist als das, was Clients für einen All-in-One-WordPress-Host zahlten, der unter der Last zusammenbrach.
---
Die ehrliche Zusammenfassung ist diese: Headless WordPress mit Astro ist eines der besseren Dinge, die Content-Sites in einer Weile passiert sind. Nicht weil es neu ist, sondern weil das Tooling der Idee endlich aufgeholt hat. WPGraphQL ist stabil, Astros Build-System ist schnell, und die Performance-Gewinne sind real und messbar.
Lass deine Architektur früh richtig laufen, besonders deine Image-Strategie und deinen Rebuild-Ansatz, dann verschwendest du später viel weniger Zeit mit Feuerbekämpfung. Das ist es wirklich.
