- .claude/agents/planer.md - .claude/agents/quorum-stimme.md - .claude/skills/bookstack-upload/SKILL.md - .claude/skills/bookstack-upload/scripts/bookstack/archiv.py - .claude/skills/bookstack-upload/scripts/bookstack/auswahl.py - .claude/skills/bookstack-upload/scripts/bookstack/beschreibung.py - .claude/skills/bookstack-upload/scripts/bookstack/bilder.py - .claude/skills/bookstack-upload/scripts/bookstack/ergebnis.py - .claude/skills/bookstack-upload/scripts/bookstack/hochladen.py - .claude/skills/bookstack-upload/scripts/bookstack/konvertierung.py - .claude/skills/bookstack-upload/scripts/bookstack/struktur.py - .claude/skills/bookstack-upload/scripts/bookstack/verweise.py - … und 33 weitere Erzeugt vom PostToolUse-Hook .vault-tools/auto-push/auto_push.py. Co-Authored-By: Claude Opus 5 <[email protected]>
14 KiB
14 KiB
type, status, title, summary, tags, created, updated
| type | status | title | summary | tags | created | updated | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| resource | reference | SEO-Arbeit an WordPress-Kundensites über WPVibe | Regeln für SEO-Audits und deren Umsetzung auf WordPress-Sites (Rank Math, Salient/WPBakery, WP Super Cache, WPCode) über den WPVibe-Connector — Arbeitsweise, Werkzeugwege, Messregeln, bekannte Fallen. Nur laden, wenn eine Website auditiert oder nach einem Audit umgebaut wird. |
|
2026-09-07 | 2026-09-30 |
SEO-Arbeit an WordPress-Kundensites über WPVibe
Angeordnet am 2026-09-07. Laden, wenn eine Website auditiert (/seo, /seo-audit) oder ein Audit-Befund auf einer WordPress-Site umgesetzt wird. Nicht bei Code-Projekten, nicht bei Dokumenten, nicht beim Depot.
Alles hier stammt aus der Arbeit an einer Kundensite zwischen dem 02.09. und dem 07.09.2026 (Audits 26 → 82 technisch, Vollaudit 67 → 70). Die Fallgeschichten und Belege liegen im Harness-Gedächtnis; hier steht nur die Regel. Wo eine Regel nur für eine bestimmte Version oder einen bestimmten Hoster belegt ist, steht das dabei.
1 Arbeitsweise
- Audit-Befunde sind Behauptungen, keine Fakten. Jeden Befund vor der Umsetzung live nachmessen (curl ohne Cache, Browser bei 375 und 1366 px). Am 07.09. waren von zehn Befunden eines Nach-Fix-Audits drei falsch: IndexNow lief, das Kachel-Clipping war nicht reproduzierbar, das „ungeplant aktivierte" Schema hatte Pascal selbst eingeschaltet. Audit-Subagenten zitieren außerdem Altbefunde aus
findings/*.mdfrüherer Läufe, die längst behoben sind. - Eigene Erfolgsmeldungen sind auch Behauptungen. Die Mittagssitzung vom 07.09. meldete „Team-Verlinkung live" und „Angebote gefixt"; beides stimmte nicht. Ein Nach-Fix-Audit läuft unabhängig und übernimmt nichts aus der Fix-Liste.
- Drei Sorten von Punkten sauber trennen: was über den Connector geht (Inhalte, Optionen, Cache); was nur Pascal kann (
.htaccess, Snippet-Freigabe und -Aktivierung, WebFTP, Google-Konten); was nur der Betreiber kann (echte Angebote, Firmenname, GBP-Pin). Die zweite und dritte Sorte landen in einerFUER-PASCAL.mdmit fertigen Blöcken und Kontrollbefehl je Block. - Nichts erfinden. Keine Rabatte, Lieferkosten, Lieferzeiten, Bewertungszahlen oder Praktiken, die nicht auf der Website, in der Preisliste oder beim Betreiber belegt sind. Was fehlt, wird als Lücke benannt („braucht Betreiberdaten"). Stammpreise sind keine Angebote.
- Ablage je Audit-Lauf unter
IT Workspace/SEO & Websitehosting/<domain>-audit/<TTMMJJJJ>/:ABSCHLUSSBERICHT.md,UMSETZUNGSPLAN.mdmit Ergebnistabelle (Befund, Maßnahme, Beleg),FUER-PASCAL.md, bei TextarbeitTEXTE-QA.mdmit dem Wortlaut. Nach-Fix-Läufe in<TTMMJJJJ>-nachher/. Nach jedem Lauf bekommt der SeedIT Workspace/SEO & Websitehosting/_MOC-seo-websitehosting.mdeinen Eintrag für diesen Lauf: Datum, Art des Laufs, gemessener Score, Link aufABSCHLUSSBERICHT.md, darunter eingerückt die Links auf die übrigen Dokumente desselben Laufordners (UMSETZUNGSPLAN.md,FUER-PASCAL.md,TEXTE-QA.mdund so weiter) ohne eigene Zusammenfassung. Den neuesten Lauf stellst du nach oben.findings/, Rohdaten und die Preisliste bekommen keinen Seed-Eintrag. Befunde früherer Läufe sind oft längst behoben (Punkt 1) und sollen nicht prominent verlinkt sein. Der Bericht verlinkt sie trotzdem, damit sie im Graphen nicht lose hängen: Nach jedem Lauf bekommtABSCHLUSSBERICHT.mdam Ende einen Abschnitt## Befunddateien dieses Laufsmit einem Wikilink mit vollem Pfad je Datei unterfindings/. Der Audit-Skill liegt außerhalb des Vaults und legt die Befunddateien ohne Link ab (AI/Regelwerk/navigation, „Links schreiben und Dateien verschieben“). /seo audit-Subagenten laufen in ihr 15-Turn-Limit (Schema, Content, Visual, SXO am 07.09.). Per SendMessage an die Task-ID fortsetzen lassen, das Teilergebnis nicht als Endstand nehmen.
2 WPVibe-Connector
- Vor jeder Arbeit
list_sitesfür das Kontingent: Free-Plan seit 2026-09-14 nur noch 100 Aufrufe je rollende 24 Stunden (vorher 300), die Zahl steht in der Antwort vonlist_sites. Massenänderungen als eine Anweisung, nicht als Schleife. Lesen bündeln (db querymitSUBSTRINGüber mehrere IDs), Live-Prüfung per curl und App-Browser statt über den Connector. - Barrierefreiheit messen mit axe-core im App-Browser (per
<script>von cdnjs nachladen, vorher einmal ganz scrollen, sonst verstecken Einblendanimationen Elemente) und einem Tab-Test von Hand; axe sieht Fokus und Tastaturbedienung nicht zuverlässig. Keine Overlay-Plugins. Den Fokusrahmen von WP Accessibility (wpa_focus, Standard #233c7f) nicht nehmen, wenn die Site grüne Flächen hat: 2,8:1 auf #009755. - Freigaben: Link erst erzeugen, wenn der Klick sofort kommt; sie können ablaufen, bevor der Klick ankommt. Nach jeder Freigabe
check_approval_statusund eine Zählabfrage am Datenbestand. „executed" heißt nicht „wirkt" (Beispiel: Option gelöscht, Sitemap trotzdem alt, siehe Abschnitt 4). - Klassifikator-Ablehnung (
Blocked by classifier) ist nicht deterministisch. Einmal über den anderen Weg versuchen: REST statt WP-CLI (PUT /wp/v2/pages/{id}stattpost update),code_snippet updatestattcreate. Nicht mehrfach denselben Aufruf wiederholen. - Inhaltsänderungen über
POST /wpvibe/v1/content/edit(match-oncestr_replaceaufpost_content, der Inhalt kommt nicht in den Kontext). Denold_contentaus dem rohenpost_contentnehmen (post get <id> --fields=post_content), nicht aus dem gerenderten HTML; Entities undwpautopverändern den Text. Dieser Weg löst keine WordPress-Hooks aus: keinsave_post, keine Rank-Math-Invalidierung, aberpost_modifiedwird gesetzt. - Emulator statt WP-CLI:
helpundhelp <familie>lesen, nicht raten.plugin deleteheißtplugin uninstall,menu deletefehlt (RESTDELETE /wp/v2/menus/{id}mit force), Semikolons indb querysind verboten,post meta updateaufrank_math_*braucht ab dem zweiten Mal--force.option patch insert|update <option> <key> <wert>schreibt einzelne Schlüssel in serialisierte Optionen, ohne die Option ganz zu laden. content/editmeldet bei einem Ausschnitt, der mitten in einem Gutenberg-Block beginnt, „parser found 0 blocks". Das prüft nur den Ausschnitt; belegt ist erst die Zählung von Öffnungs- und Schlusskommentaren der ganzen Seite perdb query.- Theme-Dateien sind über
search_filesundread_filelesbar (aktives Theme, read-only), Plugin-Dateien nicht, auch nicht mitscope=wp-content(HTTP 404, WPVibe 1.16.5). Ein unbekanntes Shortcode-Attribut erst auf einer Seite setzen und am gerenderten HTML prüfen. Wer Rank-Math-Verhalten wissen will, liest den Quelltext aus dem WordPress.org-SVN.
3 WPCode-Snippets
- Jedes PHP-Snippet braucht Freigabe und wird deaktiviert geschrieben; auch jedes
updateschaltet es aus. Pascal schaltet im Backend ein. Danachpost_statusdes Snippet-Posts (post_type = wpcode) abfragen:publishheißt an,draftheißt aus. Am 07.09. war das erste Einschalten nicht angekommen; die Aussage „ist an" war falsch, die Datenbank nicht. - Deshalb Snippet-Änderungen bündeln: eine Freigabe-plus-Einschalten-Runde je Sitzung, nicht je Einzeiler.
style_loader_tagbekommt den Handle ohne-css(wpa-style, nichtwpa-style-css); das Suffix hängt WordPress erst imid-Attribut an. Rohinhalt einer Seite immer überget_post($id)->post_content, nie überget_post_field(), das Anzeigefilter durchläuft und Shortcodes verliert.- Salient setzt
skip-lazyauf jedes Bild und schaltet natives Lazy Loading inclass-nectar-lazy.phpfest ab. Ein Lazy-Loading-Snippet, dasskip-lazyrespektiert, tut nichts. - Sicherheits-Header nie per PHP-Hook setzen: WP Super Cache liefert vor WordPress aus. Sie gehören in die
.htaccess, oberhalb des WordPress- und des Super-Cache-Blocks, sonst überschreibt WordPress sie.
4 Rank Math (belegt mit 1.0.277.2)
- Ohne verbundenes Konto oder
rank_math_registration_skip = 1liefert Rank Math nichts (kein Titel, keine Sitemap, kein Schema), obwohl das Plugin aktiv ist. Nach dem Setzenrewrite flush. - Optionen:
rank-math-options-titles(nichtrank_math_titles),rank-math-options-sitemap,rank-math-options-instant-indexing; Module inrank_math_modules; Local SEO brauchtlocal-seo. - Auf normalen Seiten lässt Rank Math bei „Schema-Typ: off" den ganzen JSON-LD-Graph weg. Filter
rank_math/schema/add_global_entitiesauf__return_truegibt Organization/Store, WebSite und WebPage auf allen Seiten aus. - Der Sitemap-Cache sind Dateien, nicht die Option:
wp-content/uploads/rank-math/rank_math_<hash>.xml, Liste inrank_math_sitemap_cache_files. Rank Math prüft die Datei. Option löschen reicht nicht,content/editund REST-PUTinvalidieren nicht. Dateien per WebFTP löschen oder Sitemap-Einstellungen im Backend speichern. - Rank Math escaped nach dem Filter
rank_math/json_ld: einhtml_entity_decodeaufhasMapim Filter kommt als&wieder heraus. Ein FAQPage-Objekt aus dem Filter mergt Rank Math in das WebPage-Objekt (@type: FAQPage,@id …#webpage); das ist gültig und gewollt. opening_hours_formatsteuert nur den Shortcode, nicht das Schema.openingHoursSpecificationkommt über einen Filter.- IndexNow: Modul
instant-indexingplus Schlüsseldatei/<key>.txtmit HTTP 200. Vor dem Befund „nicht implementiert" die Datei abrufen.
5 Salient / WPBakery
- Custom CSS liegt in
salient_redux['custom-css'](Key lautnectar/redux-framework/options-config.php) und wird bei jedem Aufruf inline ausgegeben;option patch update salient_redux custom-css "…"reicht, kein Regenerieren. Header-Icons brauchen!important, Salient setzt#header-outer[data-lhe] #top nav > ul > #social-in-menu > a { padding: 0 }. - Seiten haben oft zwei Überschriftenreihen (Desktop
vc_hidden-xs vc_hidden-sm vc_hidden-md, Mobilvc_hidden-lg). Ein Befund „H1 0×0 auf Mobil" heißt: die Mobilreihe trägt ein H2. Wer eine H1 ändert, ändert zwei Stellen. - Horizontaler Scroll kam von
column_margin_custom="7vw"einer Reihe (7vw/2 = 67 px bei 1920), nicht von der Leaflet-Karte.scrollWidthgegenclientWidthmessen, nicht raten. maximum-scale=5im Viewport: die einzige Theme-Alternative istmaximum-scale=1, user-scalable=0, schlechter. Lassen.- Google-Karte (
[nectar_gmap], belegt mit Salient 18.2.1 / Salient Core 3.1.5): Marker stehen im Shortcode-Attributmap_markers="lat|lng|Info"; ohne es rendertmap.jseinen leeren.map-marker.marker_style="nectar"zeigte keinen Pin,defaultschon.map.js(HandlenectarMap) lädt die Maps API sofort beim Seitenaufruf, ohne Salients Lazy-Script-Mechanik. Datenschutzkonform nur mit Klick-Lösung: das Klick-Snippet der Kundensite als Vorlage (Snippet-ID steht im Harness-Gedächtnis) (script_loader_tag→type="text/plain", Overlay mit Button, Klick bindet das Skript ein). Messen mit Playwright: Anfragen an Google-Hosts vor dem Klick müssen 0 sein. - Wer eine Einbindung tauscht (Karte, Schriften, Tracking), fasst im selben Schritt Datenschutzerklärung und CSP an. Am 15.09.2026 ersetzte eine Google-Karte die OSM-Karte, die Datenschutzerklärung beschrieb weiter OSM und „keine Daten an Google".
- Mobile Touch-Ziele unter 44 px im Header sind die Telefon-/E-Mail-Icons (
.button_social_group a) und der Menü-Toggle (.slide-out-widget-area-toggle a); Padding plus negativer Margin hält das Layout.
6 Hoster und Cache
- All-Inkl:
exec()aus. EWWW findet „0 Bilder", obwohl Optionen und Cron korrekt sind; Imsanity plus Converter for Media brauchen keinexec(). Vor der Plugin-Wahl fragen, ob es Binärdateien braucht. - WP Super Cache: nach jeder Änderung
cache purge; Optionsschreibungen über den Emulator purgen automatisch. Cache-Buster ist ein langer erfundener Parameter (?agentcheck=1), nie ein einbuchstabiger:wist die Kalenderwoche,mdas Datum,sdie Suche,pdie Post-ID, alle liefern eine 404-Seite mit HTTP 200. Wenn nach einer Änderung alle Seiten gleich groß sind, zuerst<title>undbody classlesen. - Cache-Header und CSP gehören in die
.htaccess(siehe Abschnitt 3). CSP erst Report-Only, eine Woche beobachten, dann scharf.
7 Messregeln
- Wortzahlen nur aus
<p>und<li>mit striktem Muster<p(?:\s[^>]*)?>, vorher<svg>,<script>,<style>entfernen.<p[^>]*>trifft<path>und zählt SVG-Icons als Absätze. Navigations-Kurzlabels sind kein Inhalt. - Eine Zahl, die vom Audit oder einer zweiten Messung um mehr als ein paar Prozent abweicht, ist ein Messfehler, bis das Gegenteil belegt ist.
- JSON-LD prüfen: Skripte extrahieren,
json.loads, dann je Seite Typen,hasMap,addressund FAQ-Antwortlängen ausgeben. Rich Results Test läuft ohne Login im App-Browser; die PageSpeed-API ist nach wenigen Läufen für den Tag erschöpft (HTTP 429), Lab-Werte deshalb datieren. - Shortcode-Lecks nach Inhaltsänderungen:
\[/?(?:toggle|vc_|nectar)[^\]]*\]auf dem gerenderten HTML muss leer sein. - Browser-Messung im App-Pane:
getBoundingClientRectund die Elternkette bis zum erstendisplay: none, nicht der Screenshot; der Screenshot-Kanal rendert nicht immer.
8 Inhalte
- Frage-Antwort-Toggles (
[toggle title="…"]) werden serverseitig gerendert und sind crawlbar; das FAQPage-Schema liest sie aus dem Rohinhalt. Zielkorridor je Antwort für KI-Zitierbarkeit 134–167 Wörter; 120–150 ist erreichbar, ohne zu schwafeln. - Jede Antwort: Faustregel mit Rechenbeispiel, Preisbeispiel mit Datum und „freibleibend, inklusive Mehrwertsteuer", zuständige Person mit Link auf
/team/. Preise nur aus der Preisliste des Betreibers, mit Stand. - Team-Verlinkung heißt Link im Inhalt, nicht im Menü.
- Schreibstil nach AI/Regelwerk/schreibstil: Sie-Form wie die Site, keine Marketingfloskeln. Ausnahme vom Listenstil: FAQ-Antworten auf der Site bleiben Fließtext im Zielkorridor oben, weil Schema und KI-Zitierbarkeit ganze Antworten lesen.
Verwandt
- AI/Regelwerk/schreibstil — Ton der Texte
- AI/Regelwerk/pruefwerkzeuge — wenn aus einer Messregel ein Skript wird
- CLAUDE