SEO-Muster für headless WordPress: die sieben Dinge, die die meisten Migrationen kaputt machen
Headless WordPress wird über Core Web Vitals, Wiederverwendung von Inhalten und redaktionelles Tempo verkauft. Wenn niemand aufpasst, begräbt es dabei sieben konkrete SEO-Signale. Wir haben genug dieser Migrationen umgesetzt, um zu wissen, welche davon Wochen an Erholung kosten und welche sich rein mechanisch richtig halten lassen.
Dieser Artikel ist die Checkliste. Er ersetzt nicht den Leistungsbereich headless WordPress, der die architektonische Begründung liefert. Er beschreibt, was wir vor, während und nach jeder Migration prüfen, in genau dieser Reihenfolge.
Kurz zusammengefasst
- Bewahren Sie kanonische URLs auf Ebene der ganzen URL, nicht nur des Slugs.
- Bewahren Sie hreflang im HTML, nicht nur in der Sitemap.
- Rendern Sie Meta-Tags und JSON-LD auf dem Server, nicht im Client.
- Migrieren Sie die Weiterleitungshistorie, bevor Sie URLs ändern, nicht danach.
- Halten Sie eine Sitemap als Quelle der Wahrheit, nicht zwei.
- Machen Sie den WordPress-Origin für den Suchindex unsichtbar.
- Übernehmen Sie Alt-Texte und strukturierte Bilddaten.
Wie Sie kanonische URLs bei einer headless-Migration halten
Eine kanonische URL ist ein Versprechen. Jeder externe Link, jeder Eintrag im Google-Index, jedes Teilen in sozialen Netzwerken verlässt sich darauf. Eine headless-Migration, die stillschweigend ein Pfadsegment kürzt, die Groß- und Kleinschreibung ändert oder Query-Parameter umsortiert, hat jedes dieser Versprechen gebrochen, ohne dass es jemand merkt.
Zwei Regeln. Erstens: Erfassen Sie den vollständigen Satz kanonischer URLs aus der bisherigen WordPress-Installation, bevor Sie das Frontend anfassen. Wir exportieren jeden veröffentlichten Beitrag, jede Seite und jede Taxonomieseite mit der URL, die Google indexiert hat; das ist die Quelle der Wahrheit. Zweitens: Schreiben Sie das Canonical in die HTML-Antwort des headless-Frontends, nicht in eine clientseitige Änderung des <head>. Generative Engines und Answer Engines parsen das initiale HTML; clientseitig geänderte Meta-Tags existieren für sie nicht.
Wenn Sie eine URL ändern müssen, leiten Sie per 301 von der alten auf die neue weiter und behalten Sie das mindestens ein Jahr lang bei.
Hreflang-Tags im HTML von headless WordPress
Mehrsprachige WordPress-Websites verwalten Übersetzungen mit WPML, Polylang oder einer eigenen Lösung. In der Datenbank stimmt die Zuordnung am Ende. Das headless-Frontend muss dann für jede Sprachvariante <link rel="alternate" hreflang="..."> in der HTML-Antwort rendern.
Das Muster, das die meisten Agenturen übersehen: hreflang muss selbstreferenzierend sein. Die englische Seite führt sich selbst und alle übersetzten Alternativen auf. Die polnische Seite führt sich selbst und alle Alternativen auf. Beide Listen stimmen überein. Der Google-Leitfaden zu lokalisierten Versionen verlangt, dass jede Sprachversion sich selbst und alle anderen aufführt; verweisen zwei Seiten nicht gegenseitig aufeinander, ignoriert Google die Tags.
Wir behandeln die hreflang-Erzeugung als Teil des Builds, nicht als Laufzeitentscheidung. Die Pfadzuordnung wird beim Build berechnet und gehasht, und jede Abweichung lässt den Build scheitern.
Serverseitiges Rendern von Meta-Tags und JSON-LD
Die häufigste SEO-Regression, die wir bei headless-Migrationen gesehen haben: Meta-Tags und JSON-LD, die nach dem Laden der Seite per JavaScript eingefügt werden. Der Browser sieht sie. Der Googlebot sieht sie manchmal. Generative Engines, Sprachassistenten und die meisten LLM-Crawler sehen sie in der Regel nicht.
Zwei Regeln. Rendern Sie Meta-Tags, Canonical, Open Graph und jeden Schema.org-JSON-LD-Block in der initialen HTML-Antwort. Mit Astro ist das der Standard. Mit Next.js bedeutet das, auf dem Server zu rendern (Metadaten im App Router oder der ältere Weg über getServerSideProps) und sich nicht darauf zu verlassen, dass next/head im Client erneut läuft.
Dasselbe gilt für Bilder: Ein <img>-Element mit alt und src im HTML ist indexierbar. Ein <img>, das erst nach einem Client-Effekt eingefügt wird, ist für die meisten Crawler und für Pipelines von KI-Trainingsdaten unsichtbar.
Yoast-JSON-LD in headless WordPress wiederverwenden
WordPress mit Yoast SEO oder Rank Math erzeugt bereits gutes JSON-LD für Article, Product und Organization. Bei einer headless-Migration ist die Versuchung groß, es im Frontend von Grund auf neu zu schreiben. Widerstehen Sie ihr.
Lesen Sie das vorhandene JSON-LD über den REST- oder GraphQL-Endpunkt aus dem WordPress-Origin. Reichen Sie es durch. Ergänzen Sie nur, was das Frontend tatsächlich weiß und WordPress nicht (zum Beispiel Build-Zeitstempel für dateModified, wenn Ihr redaktioneller Ablauf die Daten nicht anfasst). Zwei Systeme, die sich überschneidendes JSON-LD erzeugen, sind der Weg, auf dem die Berichte zu Rich-Suchergebnissen in der Search Console anfangen zu scheitern.
Für unsere eigenen Seiten nutzen wir die Komponenten aus Phase 0 in src/components/seo/: DirectAnswer, FAQ und Quote. Jede gibt ihr eigenes, minimales JSON-LD aus, ohne sich mit dem Article-Schema der Seite zu überschneiden.
Wie Sie Weiterleitungen vor einer URL-Änderung migrieren
Die Reihenfolge zählt. Die Checkliste vor der Migration erfasst jede interne und externe Weiterleitung, auch die stillen (/wp-content/... nach /uploads/..., Weiterleitungen nach Ländercode, AMP-Varianten). Das neue Frontend liefert diese Weiterleitungen am Tag null aus, bevor öffentlich auf die neuen URLs umgestellt wird.
Auf Cloudflare Pages halten wir die Datei _redirects unter der Plattformgrenze von 2000 Regeln. Ein Build, der die Grenze überschreiten würde, scheitert. Alles, was mehr als 2000 Regeln braucht, landet stattdessen in einem Worker mit Logik für parametrisierte Weiterleitungen.
Wenn das öffentliche DNS schließlich auf das neue Frontend umschaltet, ist in der Produktion keine Weiterleitung neu: Jede Regel wurde vor der Umstellung wochenlang im Build getestet.
Eine XML-Sitemap für headless WordPress
WordPress 5.5 hat eine Standard-/wp-sitemap.xml eingeführt. Yoast SEO und Rank Math bringen eigene Sitemaps mit. Das Frontend-Framework im headless-Setup erzeugt ebenfalls eine Sitemap. Drei Sitemaps auf derselben Domain sind ein sicherer Weg, die Search Console zur Verzweiflung zu bringen.
Die Regel: Wählen Sie eine kanonische Sitemap und deaktivieren oder leiten Sie die anderen weiter. Wir erzeugen die Sitemap in der Regel im Frontend-Framework, damit die URLs exakt zur öffentlichen Website passen, und leiten die Sitemap des WordPress-Origins per 301 auf die des Frontends um. Der WordPress-Origin wird damit für Suchmaschinen unsichtbar.
Wie Sie das Backend von headless WordPress auf noindex setzen
Eine headless-Migration lässt den WordPress-Origin weiterlaufen, meist auf einer Subdomain oder einem privaten Hostnamen. Er liefert weiterhin gerendertes HTML aus, hat eine funktionierende Sitemap und beantwortet REST-Anfragen. Suchmaschinen, die diesen Origin finden, indexieren ihn als Duplikat der öffentlichen Website, und das Duplikat wird nicht dasjenige sein, das rankt.
Drei Kontrollen. Die robots.txt des Origins sperrt alle Pfade außer den REST- und GraphQL-Endpunkten. Der Origin sendet bei jeder HTML-Antwort X-Robots-Tag: noindex, nofollow in den HTTP-Headern. Die Sitemap des Origins wird entfernt oder liefert 410.
Liegt Ihr Origin unter einem Pfadpräfix auf derselben Domain wie die öffentliche Website (zum Beispiel /wp-admin/ oder /wp/), gelten dieselben Kontrollen, beschränkt auf diese Pfade.
Wie Google JavaScript in einem headless-Frontend verarbeitet
Laut den Grundlagen zu JavaScript-SEO von Google Search Central verarbeitet Google JavaScript-Webanwendungen in drei Phasen: Crawling, Rendering und Indexierung. Googlebot stellt jede Seite, die den Statuscode 200 liefert, in die Rendering-Warteschlange, es sei denn, ein robots-Meta-Tag oder ein Header untersagt die Indexierung. Eine Seite kann einige Sekunden in dieser Warteschlange bleiben, die Dokumentation weist aber darauf hin, dass es auch länger dauern kann.
Für ein headless-Frontend hat das eine praktische Folge. Was in der ersten HTML-Antwort steht, wird im ersten Durchgang verarbeitet; was von JavaScript abhängt, wartet auf das Rendering. Derselbe Leitfaden hält serverseitiges Rendering oder Pre-Rendering weiterhin für sinnvoll, weil es die Website für Nutzer und Crawler schneller macht und weil nicht alle Bots JavaScript ausführen können. Deshalb behandeln wir das initiale HTML als SEO-Vertrag jeder Route: Titel, Meta-Beschreibung, Canonical, hreflang, Links und JSON-LD müssen dort stehen, ohne dass etwas ausgeführt wird.
Für Bilder gilt dieselbe Logik. Der Google-Leitfaden zu Lazy Loading nennt das im Browser integrierte Lazy Loading und die IntersectionObserver API als suchmaschinenfreundliche Methoden, weil sie Inhalte laden, sobald sie im Viewport sichtbar sind, und nicht von Scrollen oder Klicken abhängen, was die Google Suche nicht tut. Außerdem rät er davon ab, Bilder per Lazy Loading zu laden, die Nutzer sofort sehen. Geprüft wird im gerenderten HTML: Die Bild-URL muss im Attribut src des <img>-Elements stehen, was das URL-Prüftool der Search Console anzeigt.
Warum dynamisches Rendering SEO für headless WordPress nicht löst
Jahrelang war dynamisches Rendering der schnelle Ausweg für eine an WordPress angebundene Single-Page-App: Bots erhalten vorgerendertes HTML, Nutzer die JavaScript-Anwendung. Google Search Central beschreibt es heute als Behelfslösung, die nicht empfohlen wird, und empfiehlt stattdessen serverseitiges Rendering, statisches Rendering oder Hydration.
Dieselbe Seite stellt klar, dass Googlebot dynamisches Rendering in der Regel nicht als Cloaking wertet, dass es aber als Cloaking gelten kann, wenn Nutzer und Crawler völlig unterschiedliche Inhalte erhalten. In einem headless-Projekt heißt das: zwei Rendering-Pfade pflegen, die denselben Inhalt liefern müssen, und niemand merkt, wenn sie auseinanderlaufen. Ein Frontend, das auf dem Server oder im Build rendert, beseitigt diese Doppelung: Nutzer, Googlebot und Crawler ohne JavaScript erhalten dasselbe HTML.
HTTP-Statuscodes und Soft 404 in einem headless-Frontend
Fragt das Frontend die WordPress REST API nach einem Slug, den es nicht gibt, erhält es eine leere Sammlung, keinen Fehler. Rendert es daraufhin eine “Nicht gefunden”-Vorlage mit Status 200, stellt Googlebot sie wie jede gültige Seite in die Rendering-Warteschlange, und das Ergebnis ist ein Soft 404. Mit serverseitigem Rendering ist die Korrektur direkt: Bei leerer Antwort liefert das Frontend einen echten 404, oder einen 410, wenn der Inhalt absichtlich entfernt wurde.
Dasselbe gilt für Entwürfe und private Beiträge. Laut der Referenz des Posts-Endpunkts ist der Parameter status der Sammlung standardmäßig publish. Ein zurückgezogener Beitrag verschwindet also aus der Antwort, und seine Route muss mit einem Fehlercode antworten, nicht mit einer leeren Seite.
Für Routen, die nur im Browser aufgelöst werden, nennt der Leitfaden von Google zwei Strategien: eine JavaScript-Weiterleitung auf eine URL, für die der Server mit 404 antwortet (zum Beispiel /not-found), oder per JavaScript ein <meta name="robots" content="noindex"> auf Fehlerseiten setzen.
Canonical, noindex und Links per JavaScript
Derselbe Google-Leitfaden legt drei Regeln fest, die headless-Builds leicht verletzen.
- Canonical. Wird das Canonical per JavaScript gesetzt, muss es immer denselben Wert haben wie im ursprünglichen HTML; widersprüchliche oder mehrfache
rel="canonical"-Tags können zu unerwarteten Ergebnissen führen. In headless passiert das, wenn das Server-HTML das Canonical des WordPress-Origins trägt und eine Client-Komponente es auf die Frontend-URL umschreibt. - Noindex. Trifft Google auf
noindex, kann es Rendering und JavaScript-Ausführung überspringen. Ein Frontend, das während des Datenladensnoindexim initialen HTML ausliefert und es später per JavaScript entfernt, hält die Seite aus dem Index. Soll die Seite indexiert werden, darf der ursprüngliche Code keinnoindexenthalten. - Links. Google findet nur Links, die
<a>-Elemente mithref-Attribut sind, und der Leitfaden rät, keine Fragmente zum Laden unterschiedlicher Inhalte zu verwenden, sondern die History API. Ein Menü, das überonClick-Handler oder Routen wie#/beitragnavigiert, lässt die interne Struktur, die WordPress hatte, ungecrawlt.
Wie Sie das URL-Inventar aus der WordPress REST API ziehen
Die erste Regel dieses Artikels lautet, alle veröffentlichten URLs zu exportieren, bevor Sie das Frontend anfassen. Die REST API erledigt das ohne Plugin. Laut dem Handbuch zur Paginierung der REST API liefern Sammlungs-Endpunkte pro Anfrage eine begrenzte Anzahl von Einträgen; per_page nimmt eine ganze Zahl von 1 bis 100 an, page bestimmt, welche Ergebnisseite zurückkommt. Jede Antwort enthält den Header X-WP-Total mit der Gesamtzahl der Datensätze und X-WP-TotalPages mit der Gesamtzahl der Seiten. Es genügt, X-WP-TotalPages bei der ersten Anfrage an /wp-json/wp/v2/posts?per_page=100 auszulesen und die restlichen Seiten abzuarbeiten.
Aus der Posts-Referenz zählen pro Beitrag zwei Felder: link, die URL des Beitrags so, wie WordPress sie veröffentlicht, und modified_gmt, das Datum der letzten Änderung in GMT. Das erste ist die Liste, mit der jede Route des neuen Frontends abgeglichen wird; das zweite speist lastmod in der Sitemap. Das Argument modified_after beschränkt die Antwort auf Beiträge, die nach einem ISO-8601-Datum geändert wurden, was inkrementelle Builds erlaubt, ohne jedes Mal den gesamten Inhalt zu laden. Dasselbe Paginierungsmuster funktioniert für /wp/v2/pages und die Taxonomie-Endpunkte.
URL-Auflösung, Vorschauen und Caching mit WPGraphQL
WPGraphQL ist ein kostenloses Open-Source-Plugin, das WordPress ein erweiterbares GraphQL-Schema und eine GraphQL-API gibt. Die Dokumentation zeigt, wie man einen Beitrag über seine URI, also den Pfad zum Beitrag, als Kennung abfragt. Für SEO zählt das, weil öffentliche Route und Inhalt aus derselben Quelle kommen: Das Frontend fragt den Knoten über den Pfad ab, den es erhält, und braucht keine eigene Tabelle, die Routen in IDs übersetzt.
Vorschauen verlangen mehr Sorgfalt. Laut der Dokumentation zu Vorschauen kann WPGraphQL die unveröffentlichte Version eines Beitrags liefern, die Anfrage muss aber mit einer Methode authentifiziert sein, die WordPress erkennt. Ist sie das nicht, liefert WPGraphQL den veröffentlichten Knoten, als wäre keine Vorschau angefordert worden, ohne Fehlermeldung. Eine Vorschau-Route mit kaputter Authentifizierung zeigt also stillschweigend den veröffentlichten Inhalt. Deshalb tragen Vorschau-Routen noindex, stehen nicht in der Sitemap und umgehen den öffentlichen Cache, und das Feld isPreview bestätigt, dass die Vorschau tatsächlich angewendet wurde.
Das Caching entscheidet, wie lange Änderungen an Titel, Beschreibung oder Canonical in WordPress brauchen, bis sie im HTML ankommen. Die Dokumentation zur Performance nennt die Unterstützung von GET-Anfragen, die ein CDN oder Proxy cachen kann, und beschreibt, dass die Erweiterung WPGraphQL Smart Cache Antworten mit dem Header X-GraphQL-Keys markiert und bei Inhaltsänderungen ein Ereignis mit den betroffenen Tags auslöst, damit der Host nur diese Dokumente leert. Mit dieser Invalidierung erreicht eine redaktionelle Änderung an SEO-Metadaten das Frontend, ohne dass der Cache erst ablaufen muss.
Weitere Leitfäden zu SEO für headless WordPress
Dieser Artikel ergänzt den Leistungsbereich headless WordPress. Für die Entscheidungsphase lesen Sie Headless WordPress, Next.js vs Astro 2026. Die größere Sichtbarkeitsfrage einschließlich LLM-Zitaten behandelt der Leitfaden zur Sichtbarkeit in KI und LLMs: Er beschreibt verbindlich, was wir für AEO und GEO auf diesem SEO-Fundament umsetzen.







