Markus Michalski FAQ

Sylius SEO Suite Pro: SEO-Audit

Der SEO-Audit prüft Produkte und Kategorien auf fehlende, zu lange und doppelte Titel und Beschreibungen, fehlende Bilder und noindex. Start per Dashboard-Button oder Cronjob, mit Snapshot, Lock und Limits.

English Version

Zurück zur Übersicht

Sylius SEO Suite Pro: SEO-Audit

Der SEO-Audit prüft die Produkte und Kategorien eines Channels auf SEO-Probleme, die Du im Admin selbst beheben kannst, und listet die Funde mit einem Link zum jeweiligen Produkt oder zur Kategorie. Du startest ihn per Button im Dashboard oder per Console-Command. Erreichbar ist er über den Button "SEO-Audit" oben auf der Seite "SEO Suite Pro".

Der Audit prüft, was der Storefront wirklich ausliefert: Titel und Beschreibung einer Seite nach der Prioritätskette (manueller Text, dann SEO-Template, dann Fallback, siehe SEO-Templates). Ein Produkt, dessen Titel aus einem Template kommt, wird also nicht als "Titel fehlt" gemeldet.

Was geprüft wird

Geprüft wird pro Channel und pro Sprache des Channels, für jedes aktive Produkt und jede aktive Kategorie, die im Channel verfügbar ist. Deaktivierte Produkte und Kategorien sowie die anderer Channels werden nicht angesehen. Fehlt eine Übersetzung in einer Sprache, wird das Produkt in dieser Sprache nicht geprüft.

Code Prüft Schwere Schwellwert
title_missing Kein manueller Meta-Titel und kein Titel-Template greift, der Seitentitel ist also nur der Name warning keiner
title_too_long Der ausgelieferte Titel ist zu lang (der Detailwert nennt die Länge) warning mehr als 60 Zeichen (seo_templates.title_max_length)
title_duplicate Derselbe Titel steht bei mehr als einem Produkt (oder einer Kategorie) des Channels in derselben Sprache (der Detailwert nennt die Anzahl) warning ab 2 gleichen Titeln
description_missing Die ausgelieferte Meta-Description ist leer warning keiner
description_too_long Die ausgelieferte Meta-Description ist zu lang (der Detailwert nennt die Länge) info mehr als 155 Zeichen (seo_templates.description_max_length)
description_duplicate Dieselbe Beschreibung bei mehr als einem Produkt (oder einer Kategorie), wie bei den Titeln warning ab 2 gleichen Beschreibungen
product_without_image Ein Produkt ohne jedes Bild (einmal pro Produkt, nicht pro Sprache) warning kein Bild
noindex Produkt oder Kategorie steht auf noindex; oft gewollt, wird aber gelistet, damit eine vergessene Einstellung auffällt info keiner

Es gibt die Schweren error, warning und info. Die acht eingebauten Checks nutzen nur warning und info; error steht Deinen eigenen Checks zur Verfügung. Duplikate ignorieren Groß-/Kleinschreibung und mehrfache Leerzeichen. Ein leerer Text ist nie ein Duplikat, er wird stattdessen als fehlend gemeldet. Die Längen-Schwellwerte sind keine eigenen Audit-Einstellungen: Sie folgen den Grenzen der SEO-Templates, damit der Audit und die Template-Kürzung dieselbe Messlatte nutzen.

Unter den Channels zeigt das Dashboard zusätzlich die zehn meistaufgerufenen 404-Pfade, die kein aktiver Redirect abdeckt, live aus dem 404-Log (siehe Redirects). Jeder Pfad hat einen Link, der das Redirect-Formular vorausgefüllt öffnet. Dieser Block gehört nicht zum Snapshot und funktioniert auch ohne die Audit-Tabellen.

Was nicht geprüft wird

Eigene Prüfungen sind möglich, siehe unten.

So läuft ein Audit ab

Ein Lauf ist ein Snapshot: Er schreibt seine Funde in mmd_sylius_seo_suite_pro_audit_issue und den Lauf selbst in mmd_sylius_seo_suite_pro_audit_run (Status running, done oder failed, dazu die Anzahl der Funde pro Check). Dashboard und Liste lesen nur diese Tabellen, beim Öffnen wird nichts berechnet.

Nur ein erfolgreicher Lauf (done) gilt als aktueller Stand. Liste und Zähler zeigen den neuesten done-Lauf jedes Channels. Ein fehlgeschlagener Lauf (seine Funde sind unvollständig) ersetzt ihn nie: Das Dashboard weist dann darauf hin, dass der letzte Lauf fehlgeschlagen ist, und zeigt weiter den letzten guten Stand.

graph TD
    A["Start für einen Channel"] --> B{"Lock des Channels frei?"}
    B -->|"nein, Heartbeat frisch"| C["Abbruch: Audit läuft bereits"]
    B -->|"ja, oder Heartbeat älter als stale_after_minutes"| D["Lock nehmen, Lauf als running anlegen"]
    D --> E["Seite mit page_size Produkten laden und prüfen"]
    E --> F["Funde der Seite schreiben, Heartbeat setzen, Speicher leeren"]
    F --> G{"Noch Seiten und unter max_subjects?"}
    G -->|"ja"| E
    G -->|"max_subjects erreicht"| H["Abgeschnitten: Lauf endet als done mit Hinweis max_subjects"]
    G -->|"nein"| I["Duplikat-Checks schreiben ihre Funde"]
    I --> J["Lauf als done abschließen, Lock lösen"]
    H --> J
    J --> K["Ältere Läufe über keep_runs hinaus löschen"]
    E -->|"Fehler"| L["Lauf als failed abschließen, Lock lösen"]

Mit audit.max_subjects (20000) werden Produkte und, getrennt davon, Kategorien pro Channel begrenzt. Ein größerer Channel wird abgeschnitten: Der Lauf endet als done mit dem Hinweis "stopped at the subject limit". Die Funde sind echt, decken aber nur einen Teil des Katalogs ab. Der Console-Command meldet das als Fehler (Exit-Code 1), damit Du es im Cronjob bemerkst.

Audit starten

Dashboard

Im Admin: "Run audit now" auf der Karte eines Channels im Audit-Dashboard (ein POST mit CSRF-Token). Die Route liegt hinter der Admin-Firewall wie jeder andere Admin-Bildschirm. Der Request dauert so lange wie der Lauf (das PHP-Zeitlimit wird auf 600 Sekunden gesetzt, die Session wird vor dem Lauf freigegeben, damit andere Admin-Tabs nicht warten). Das Ergebnis erscheint als Flash-Meldung: Erfolg, Warnung bei Abschneiden oder "läuft bereits", Fehler bei fehlenden Tabellen oder unbekanntem Channel.

Der Button läuft synchron und ist auf 600 Sekunden begrenzt. Der Lauf leert außerdem den Entity Manager und löst damit alles ab, was der Request geladen hat, darunter das User-Objekt des Administrators (es wird beim nächsten Request neu geladen). Das ist für kleine Kataloge in Ordnung, für große nimm den Console-Command oder einen Cronjob.

Console

Für jeden Channel oder einen bestimmten:

bin/console mmd:seo-suite-pro:audit:run
bin/console mmd:seo-suite-pro:audit:run --channel=shop

Der Exit-Code ist 0, wenn jeder Lauf abgeschlossen wurde, 1, wenn ein Lauf abgelehnt wurde (läuft bereits), am Limit abgeschnitten wurde oder fehlschlug, und 2 bei einem unbekannten Channel. Ein nächtlicher Cronjob um 03:30 Uhr:

30 3 * * * cd /var/www/shop && bin/console mmd:seo-suite-pro:audit:run --no-interaction

Das Dashboard und die Liste

Das Dashboard zeigt pro Channel den neuesten Lauf mit Zählern pro Check, den Button zum Starten und die 404-Pfade ohne Redirect. Die Funde-Liste ist ein reines Lese-Grid mit dem Stand des neuesten done-Laufs jedes Channels, filterbar nach Code des Produkts oder der Kategorie, Channel, Check, Schwere und Typ.

Eigene Checks

Implementiere Mmd\SyliusSeoSuiteProPlugin\Audit\AuditCheckInterface (oder erweitere AbstractAuditCheck). Jeder Service, der das Interface implementiert, wird automatisch mit mmd_sylius_seo_suite_pro.audit_check getaggt; mit priority am Tag legst Du die Reihenfolge fest. Der Runner ruft start() einmal pro Lauf, inspect() für jedes Produkt und jede Kategorie in jeder Sprache und finish() am Ende auf. Ein vollständiges Beispiel mit den Übersetzungsschlüsseln für die Labels findest Du unter Erweitern.

Einstellungen

Alle Schlüssel sind optional und stehen unter mmd_sylius_seo_suite_pro.audit:

Einstellung Standard Beschreibung
audit.keep_runs 3 Anzahl der Läufe pro Channel, die erhalten bleiben
audit.max_subjects 20000 Produkte und, getrennt davon, Kategorien, die ein Lauf pro Channel höchstens prüft
audit.stale_after_minutes 10 Ein Lauf ohne Heartbeat für diese Zeit gilt als tot und blockiert nicht mehr
audit.page_size 200 Produkte oder Kategorien, die auf einmal geladen werden
mmd_sylius_seo_suite_pro:
    audit:
        keep_runs: 3
        max_subjects: 20000
        stale_after_minutes: 10
        page_size: 200

Kosten

Ein Lauf liest jedes aktive Produkt und jede aktive Kategorie des Channels einmal. Ohne SEO-Templates braucht eine Seite mit 200 Produkten eine konstante Zahl an Queries (die IDs, die Produkte mit allen Übersetzungen, die Bildzahlen, der Channel). Mit Templates kommen die Queries der Placeholder-Provider dazu (Attributwerte pro Produkt, {taxon.main} pro Produkt), genau so viel, wie das Rendern der Produktseite kostet. Dann wächst die Zahl der Queries mit der Zahl der Produkte. Das Schreiben der Funde ist ein Bulk-Insert pro Seite. Nichts davon läuft bei einem Shop-Request: Storefront und Shop API berühren die Audit-Tabellen nie.

Schritte im Host-Projekt

Nach jedem Update des Plugins führst Du mmd:seo-suite-pro:setup aus (siehe Installation), es legt die beiden Audit-Tabellen an. Ohne sie zeigt das Dashboard einen Hinweis statt der Zahlen, der Console-Command meldet die fehlende Migration, die Funde-Liste antwortet mit einem Fehler und der 404-Block funktioniert weiter. Storefront und Shop API sind nicht betroffen. Bei Problemen hilft Fehlerbehebung.

Shop API / Headless

Der Audit ist ein Back-Office-Feature: Ein Administrator startet ihn und liest ihn im Admin, kein Besucher und kein Headless-Frontend nutzt ihn. Die Logik liegt in AuditRunnerInterface und wird vom Console-Command und vom Dashboard-Button gemeinsam genutzt. Es gibt deshalb keine API-Resource dafür. Was die Shop API liefert, ist die SEO-Resource der Seiten selbst.