Zum Inhalt

Konfiguration

Alle Einstellungen befinden sich in der Erweiterungskonfiguration: Admin Tools → Settings → Extension Configuration → nt_ai.

Werte lassen sich auch je Umgebung über den Standard-TYPO3-Mechanismus in config/system/settings.php überschreiben:

$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['nt_ai']['provider']['default'] = 'openai';

Für Geheimnisse können Umgebungsvariablen-Platzhalter direkt im Erweiterungskonfigurationsformular verwendet werden:

provider.anthropic.apiKey = %env(NT_AI_ANTHROPIC_KEY)%
provider.openai.apiKey    = %env(NT_AI_OPENAI_KEY)%

nt-ai löst diese zur Laufzeit über getenv() auf.

Modellnamen aus der Umgebung

Modellnamen verstehen denselben Platzhalter. Ein Projekt kann sie damit aus der versionierten config/system/settings.php heraushalten und das Modell wechseln, indem es eine Umgebungsvariable ändert — ohne Commit und ohne Deployment:

// config/system/settings.php (Auszug)
'EXTENSIONS' => [
    'nt_ai' => [
        'provider' => [
            'openai' => [
                'apiKey' => '%env(NT_AI_OPENAI_KEY)%',
                'model' => '%env(AI_MODEL_OPENAI)%',
            ],
        ],
    ],
],
# .env
AI_MODEL_OPENAI=gpt-4.1-mini

Das gilt für die Modell-Einstellung jedes Anbieters und für tts.model. Der Platzhalter muss den ganzen Wert bilden, der Variablenname darf A–Z, 0–9 und _ enthalten. Die Variable muss für PHPs getenv() sichtbar sein — gesetzt vom Webserver oder Container oder aus einer .env geladen, etwa über helhum/dotenv-connector.

Ein bewusster Unterschied zu den API-Schlüsseln: Ist die Variable leer oder fehlt sie, gilt der unten genannte Standard des Anbieters, kein leerer Wert. Ein fehlender API-Schlüssel macht einen Anbieter zu Recht unverfügbar. Ein leerer Modellname dagegen ginge an den Anbieter und ließe jeden Aufruf scheitern — ein vergessener ENV-Eintrag soll die KI-Funktionen nicht lahmlegen. Derselbe Rückfall gilt für ein im Backend leer gespeichertes Modellfeld.

Verfügbar ab 1.15.0. Wörtliche Modellnamen funktionieren unverändert weiter.

Anbieter-Einstellungen

provider.default legt fest, welcher Anbieter verwendet wird, wenn bei einem Aufruf kein Anbieter angegeben ist. Mögliche Werte: anthropic, openai, gemini, deepseek, mistral, groq, ollama.

Anthropic Claude

Einstellung Typ Standard Beschreibung
provider.anthropic.apiKey string (leer) API-Schlüssel von console.anthropic.com. Erforderlich zur Nutzung von Claude. Unterstützt %env(VAR)%-Platzhalter.
provider.anthropic.model string claude-sonnet-4-5 Modell-Bezeichner. Beispiele: claude-opus-4-5, claude-haiku-4-5. Vision wird bei allen Claude-3+- und 4+-Modellen unterstützt. Unterstützt %env(VAR)%, siehe Modellnamen aus der Umgebung.
provider.anthropic.baseUrl string https://api.anthropic.com/v1 Nur überschreiben, wenn Anthropic über eine eigene Infrastruktur als Proxy betrieben wird.

OpenAI

Einstellung Typ Standard Beschreibung
provider.openai.apiKey string (leer) API-Schlüssel von platform.openai.com. Erforderlich zur Nutzung von OpenAI.
provider.openai.model string gpt-4o-mini Beispiele: gpt-4o, gpt-4o-mini, gpt-4-turbo. Für die Alt-Text-Generierung ein Vision-Modell verwenden (gpt-4o, gpt-4o-mini). Unterstützt %env(VAR)%, siehe Modellnamen aus der Umgebung.
provider.openai.baseUrl string https://api.openai.com/v1 Überschreiben für Azure OpenAI, OpenRouter, LM Studio oder andere OpenAI-API-kompatible Endpunkte.

Google Gemini

Einstellung Typ Standard Beschreibung
provider.gemini.apiKey string (leer) API-Schlüssel von aistudio.google.com. Erforderlich zur Nutzung von Gemini.
provider.gemini.model string gemini-2.0-flash Beispiele: gemini-2.5-pro, gemini-2.0-flash, gemini-1.5-flash. Alle aufgeführten Modelle unterstützen Vision. Unterstützt %env(VAR)%, siehe Modellnamen aus der Umgebung.
provider.gemini.baseUrl string https://generativelanguage.googleapis.com/v1beta Überschreiben bei Proxy-Setups.

DeepSeek

Einstellung Typ Standard Beschreibung
provider.deepseek.apiKey string (leer) API-Schlüssel von platform.deepseek.com. Erforderlich zur Nutzung von DeepSeek.
provider.deepseek.model string deepseek-chat deepseek-chat = DeepSeek-V3 (allgemein), deepseek-reasoner = R1 (Chain-of-Thought). Keines der Modelle unterstützt Vision. Unterstützt %env(VAR)%, siehe Modellnamen aus der Umgebung.
provider.deepseek.baseUrl string https://api.deepseek.com/v1 Überschreiben bei Proxy-Setups.

Mistral AI

Einstellung Typ Standard Beschreibung
provider.mistral.apiKey string (leer) API-Schlüssel von console.mistral.ai.
provider.mistral.model string mistral-small-latest Beispiele: mistral-large-latest, pixtral-large-latest (Vision). Vision ist nur bei pixtral-*-Modellen verfügbar. Unterstützt %env(VAR)%, siehe Modellnamen aus der Umgebung.
provider.mistral.baseUrl string https://api.mistral.ai/v1 Überschreiben bei Proxy-Setups.

Groq

Einstellung Typ Standard Beschreibung
provider.groq.apiKey string (leer) API-Schlüssel von console.groq.com.
provider.groq.model string llama-3.3-70b-versatile Beispiele: llama-3.1-8b-instant, gemma2-9b-it. Groq unterstützt kein Vision. Unterstützt %env(VAR)%, siehe Modellnamen aus der Umgebung.
provider.groq.baseUrl string https://api.groq.com/openai/v1 Überschreiben bei Proxy-Setups.

Ollama (lokal)

Einstellung Typ Standard Beschreibung
provider.ollama.baseUrl string http://localhost:11434 URL der Ollama-Instanz. Bei getrennten Containern für TYPO3 und Ollama die container-interne URL verwenden (z. B. http://host.docker.internal:11434).
provider.ollama.model string llama3.2 Lokal installierter Modellname. Für Vision-Funktionen zuerst ein multimodales Modell installieren: ollama pull llama3.2-vision Unterstützt %env(VAR)%, siehe Modellnamen aus der Umgebung.

Verhalten

Einstellung Typ Standard Beschreibung
behavior.timeout integer (Sekunden) 60 Maximale Wartezeit für KI-Anfragen. Bei sehr langsamen lokalen Modellen erhöhen.
behavior.maxTokens integer 2048 Maximale Token pro Antwort. Gilt für alle Anbieter.
behavior.logRequests boolean aus Wenn aktiv, wird jeder KI-Aufruf über den Standard-TYPO3-Logger protokolliert. Hilfreich zum Debuggen, kann jedoch sensible Prompt-Inhalte in Log-Dateien schreiben. Im Produktivbetrieb deaktiviert lassen.
behavior.defaultLanguage string (ISO 639-1) en Wird verwendet, wenn bei einem Aufruf keine Sprache angegeben ist. Beeinflusst Inhaltserstellung, Übersetzungen und Alt-Texte.

Alt-Text-Anpassung

Diese Einstellungen formen die von der KI erzeugten Alt-Texte so, dass sie zur Tonalität und Barrierefreiheitsrichtlinie Ihrer Website passen. Die Einstellungen gelten für jede Alt-Text-Generierung, einschließlich Massen-CLI-Läufen und den „Alt-Text generieren"-Schaltflächen.

Einstellung Typ Standard Beschreibung
altText.customInstructions mehrzeiliger Text (leer) Freiformige zusätzliche Regeln für die KI. Eine Anweisung pro Zeile. Werden wörtlich an den System-Prompt angehängt.
altText.maxLength integer 125 Weiche Obergrenze für die Alt-Text-Länge in Zeichen. 0 deaktiviert die Begrenzung. Die KI wird angewiesen, das Limit einzuhalten; die Ausgabe wird zusätzlich hart an Wortgrenzen gekürzt, falls das Modell es überschreitet. WCAG-/Screenreader-Best-Practice liegt bei ca. 125 Zeichen.
altText.style enum concise concise — ein kurzer Satz. descriptive — 1–2 Sätze. detailed — 2–3 Sätze, geeignet für Diagramme und Inhaltsbilder.
altText.forbidImagePrefix boolean an Entfernt Formulierungen wie „Bild von…", „Abbildung zeigt…", „Image of…" aus dem Prompt und defensiv aus der Antwort. Screenreader kündigen Grafiken bereits an, solche Präfixe sind daher überflüssig.
altText.includeDetectedText boolean an Die KI transkribiert sichtbaren Text im Bild (Schilder, Screenshots, Beschriftungen, Verpackungen). Wichtig für die Barrierefreiheit — Text in Bildern ist für Screenreader-Nutzer sonst nicht zugänglich.
altText.tone string neutral, factual Freiformige Tonbeschreibung. Beispiele: friendly, casual (Blogs), marketing, enthusiastic (Landingpages), technical, precise (Dokumentation).
altText.brandContext string (max. 500 Zeichen) (leer) Ein kurzer Hinweis zu Ihrer Website oder Marke, der jeder Alt-Text-Anfrage beigefügt wird. Nützlich für kontextsensitive Beschreibungen.

Strikte Alt-Text-Richtlinie — deutsches Kunstmuseum

altText.style             = descriptive
altText.maxLength         = 200
altText.tone              = neutral, sachlich
altText.brandContext      = Museum für moderne Kunst. Bildbeschreibungen für ein Fachpublikum, Künstlernamen nur wenn klar erkennbar.
altText.customInstructions:
  Bei Kunstwerken: Stil, Material und ungefähre Epoche nennen.
  Personen nur als "Besucher", "Mitarbeiter" o.ä. bezeichnen.
  Texttafeln und Beschriftungen wörtlich übernehmen.

Audit-Einstellungen

Einstellung Typ Standard Beschreibung
audit.enabled boolean an Hauptschalter für das Barrierefreiheits-Audit-Backend-Modul.
audit.autoOnSave boolean aus Wenn aktiv, wird nach jedem Speichern einer Seite im Backend automatisch ein Audit ausgelöst (durch audit.autoCooldown ratenbegrenzt).
audit.autoCooldown integer (Sekunden) 120 Mindestabstand zwischen automatischen Audits für dieselbe Seite. Verhindert Audit-Stürme bei schnellem Speichern durch Redakteure.
audit.aiRules boolean an Legt fest, ob KI-gestützte Audit-Regeln ausgeführt werden. Bei Deaktivierung laufen nur deterministische regelbasierte Prüfungen. KI-Regeln werden auch automatisch übersprungen, wenn kein Anbieter konfiguriert ist.
audit.retentionDays integer (Tage) 90 Audit-Berichte, die älter als dieser Wert sind, können über den Standard-TYPO3-Garbage-Collection-Task gelöscht werden. 0 deaktiviert die Bereinigung.
audit.maxReportsPerPage integer 10 Maximale Anzahl gespeicherter Berichte pro Seite. Ältere Berichte werden nach jedem neuen Audit-Lauf automatisch bereinigt.
audit.explainPrompt mehrzeiliger Text (integriert) Benutzerdefinierte Prompt-Vorlage für KI-generierte Befund-Erläuterungen. Verfügbare Platzhalter: {ruleId}, {severity}, {message}, {wcagReference}, {snippet}.

Barrierefreiheitserklärung

Angaben für den Reiter „Erklärung" im Audit-Modul, der aus den Audit-Daten einen Entwurf einer Erklärung zur Barrierefreiheit erzeugt (siehe Benutzerhandbuch → „Barrierefreiheitserklärung erstellen").

Einstellung Typ Standard Beschreibung
declaration.targetPageUid integer 0 Zielseite, auf der die Erklärung veröffentlicht wird. 0 = automatisch die Seite mit dem Slug /barrierefreiheit.
declaration.organisation string (leer) Name der Organisation in der Erklärung. Leer = Website-Titel aus der Site-Konfiguration.
declaration.feedbackContact Text (leer) Ansprechpartner für Barrierefreiheits-Feedback (Name, E-Mail, Telefon). Pflichtangabe der Erklärung.
declaration.enforcementBody Text (leer) Zuständige Durchsetzungs-/Schlichtungsstelle (für Unternehmen unter BFSG i. d. R. die Marktüberwachungsstelle der Länder).
declaration.enforcementUrl string (leer) Link zur zuständigen Stelle (optional).
declaration.measures Text (integriert) Bereits umgesetzte Maßnahmen, eine pro Zeile oder mit \| getrennt. Installierte Schwester-Erweiterungen (nt-lingua) und das nt-ai-Audit werden automatisch ergänzt.

Publishing Quality Gate

Warnt beim Veröffentlichen einer Seite vor offenen Barrierefreiheits-Findings oder blockiert die Veröffentlichung, bis kritische Punkte behoben sind. Das Gate nutzt den zuletzt gespeicherten Audit-Bericht der Seite — daher audit.autoOnSave aktiviert lassen, damit der Bericht aktuell bleibt. Ablauf: beheben → speichern (re-Audit) → Bericht aktualisiert → Veröffentlichen erlaubt.

Einstellung Typ Standard Beschreibung
audit.qualityGate Optionen (off/warn/block) off warn: Flash-Warnung beim Veröffentlichen. block: Veröffentlichen wird verhindert (Seite bleibt versteckt), solange das Gate nicht bestanden ist.
audit.qualityGateSeverity Optionen (error/warning) error Ab welchem Schweregrad das Gate greift. error = nur kritische Fehler, warning = Fehler und Warnungen.
audit.qualityGateScope Optionen (onPublish/onSave) onPublish onPublish: nur beim Sichtbarschalten (hidden=0). onSave: bei jedem Speichern einer nicht versteckten Seite.
audit.qualityGateAdminBypass boolean an Administratoren dürfen trotz Findings veröffentlichen (erhalten nur eine Warnung).

Für Pipelines: nt_ai:audit --fail-on=error (bzw. warning) liefert Exit-Code ≠ 0 bei Findings — nutzbar als CI/CD-Gate.

PDF-Barrierefreiheit (Upload-Gate)

Prüft PDFs beim Backend-Upload auf Barrierefreiheit (getaggtes PDF, Textebene, Dokumentsprache, Titel, Alternativtexte …) und warnt oder blockiert je nach Modus. Unabhängig vom Modus wird bei jedem Backend-PDF-Upload ein Bericht für das Modul Medien → PDF-Barrierefreiheit gespeichert. Frontend-Formular-Uploads sind ausgenommen. Details zu den Prüfregeln: Benutzerhandbuch.

Einstellung Typ Standard Beschreibung
pdf.uploadGate Optionen (off/warn/block) off warn: Datei wird gespeichert, der Redakteur erhält eine bleibende Warnmeldung mit den Befunden. block: Der Upload wird mit einer Meldung inkl. Befunden abgelehnt — es entsteht keine Datei.
pdf.uploadGateSeverity Optionen (error/warning) warning Ab welchem Schweregrad das Gate greift. warning = Fehler und Warnungen (z. B. fehlender Dokumenttitel), error = nur kritische Fehler.
pdf.uploadGateAdminBypass boolean an Administratoren dürfen trotz Befunden hochladen (erhalten nur die Warnung statt einer Blockade).

Für Bestandsprüfung und Pipelines: nt_ai:pdf-audit [--limit N] [--force] [--fail-on=error|warning] — rein PHP-basiert (keine Systemwerkzeuge nötig), unveränderte Dateien werden übersprungen.

Token-Tracking und Kostenschätzung

Einstellung Typ Standard Beschreibung
tokenTracking.enabled boolean aus Wenn aktiv, wird jeder KI-Aufruf in tx_ntai_token_usage protokolliert. Erforderlich für die Token-Verbrauchs-Dashboard-Widgets.
tokenTracking.currency Optionen USD Anzeigewährung für geschätzte Kosten. USD → ~$0.19, EUR → ~0,18 €.
tokenTracking.eurRate float 0.92 USD-zu-EUR-Umrechnungskurs. Wird nur verwendet, wenn die Währung auf EUR gesetzt ist.
tokenTracking.customPricing Text (JSON) (leer) Integrierte Modellpreistabelle überschreiben oder erweitern. Preise in USD pro 1.000.000 Token. Präfix-Matching wird angewendet — "gpt-4o" trifft auf gpt-4o-2024-08-06.
{
    "my-fine-tuned-gpt4o": {"input": 4.00, "output": 12.00},
    "custom-ollama-model": {"input": 0.00, "output": 0.00}
}

Integrierte Preistabelle (Stand 2026-07)

Modell-Präfix Anbieter Input $/1M Output $/1M
gpt-4o-mini OpenAI 0.15 0.60
gpt-4o OpenAI 2.50 10.00
claude-haiku-4 Anthropic 0.80 4.00
claude-sonnet-4 Anthropic 3.00 15.00
claude-opus-4 Anthropic 15.00 75.00
gemini-2.0-flash Google 0.10 0.40
gemini-2.5-pro Google 1.25 10.00
deepseek-chat DeepSeek 0.27 1.10
mistral-small Mistral AI 0.20 0.60
llama-3.3-70b Groq 0.59 0.79

Die vollständige Tabelle befindet sich in EXT:nt_ai/Configuration/ModelPricing.php. Unbekannte Modelle werden im Dashboard-Widget als Warnung angezeigt. TTS-Modelle (tts-1, tts-1-hd, gpt-4o-mini-tts) sind dort mit dem Preis pro 1 Mio. Zeichen hinterlegt.

Vorlesen (TTS)

Engine, Tempo und Vorlese-Bereich werden in den Site-Einstellungen gewählt (Kategorie „Vorlesen (TTS)"). Die folgenden Werte gelten nur für die Cloud-Engine und stehen in der Erweiterungskonfiguration (Tab „Vorlesen (TTS)"):

Einstellung Typ Standard Beschreibung
tts.cloudProvider Optionen openai Anbieter der Premium-Sprachausgabe. API-Key = der des jeweiligen Providers (Tab „Anbieter-Einstellungen").
tts.voice string alloy Stimme des Anbieters (OpenAI: alloy, echo, fable, onyx, nova, shimmer).
tts.model string tts-1 TTS-Modell (OpenAI: tts-1, tts-1-hd, gpt-4o-mini-tts). Unterstützt %env(VAR)%, siehe Modellnamen aus der Umgebung.
tts.rateLimit integer 30 Max. neue Cloud-Anfragen pro IP und Minute (Schutz vor Bots/Massennutzung). 0 = unbegrenzt; Cache-Treffer zählen nicht.

Der Cloud-Endpunkt /nt-ai/tts antwortet nur, wenn die Site-Engine auf cloud steht; er weist Cross-Site-Anfragen ab und ist rate-limitiert. Erzeugte Audios werden serverseitig gecacht, wiederholte Vorlesevorgänge desselben Textes sind kostenlos. Details siehe Benutzerhandbuch → Vorlesefunktion.

Lighthouse-Monitoring

Öffentlich erreichbare URLs erforderlich

Die PSI-API kann ausschließlich öffentlich zugängliche URLs analysieren. Diese Funktion auf Staging- oder Produktivservern verwenden, nicht auf lokalen DDEV-Instanzen — Google kann *.ddev.site-URLs nicht erreichen.

Einstellung Typ Standard Beschreibung
lighthouse.apiKey string (leer) Google-API-Schlüssel von console.cloud.google.com (API „PageSpeed Insights" aktivieren). Ohne Schlüssel sind Anfragen auf ~25 pro 100 Sekunden begrenzt. Im Produktivbetrieb immer einen Schlüssel konfigurieren. Unterstützt %env(NT_AI_LIGHTHOUSE_KEY)%.
lighthouse.strategy Optionen mobile Geräteprofil für Lighthouse. mobile (Standard), desktop oder both (führt zwei PSI-Aufrufe pro Seite durch — verdoppelt den Kontingentverbrauch).
# Alle Seiten, mobile Strategie (liest Einstellung aus der Erweiterungskonfiguration).
vendor/bin/typo3 nt_ai:lighthouse

# Seite 42 und vollständiger Teilbaum, nur Desktop.
vendor/bin/typo3 nt_ai:lighthouse 42 99 --strategy=desktop

# Unterseiten von Seite 1, beide Strategien ausführen.
vendor/bin/typo3 nt_ai:lighthouse 1 1 --strategy=both

Ergebnisse werden als rein additive Verlaufshistorie in tx_ntai_lighthouse_report gespeichert. Das Dashboard-Widget Lighthouse-Scores zeigt die durchschnittlichen Scores über alle analysierten Seiten.

Score-Schwellenwert-Alarme

Einstellung Typ Standard Beschreibung
alerting.enabled boolean aus Hauptschalter. Kein E-Mail wird versendet, solange dieser deaktiviert ist.
alerting.recipient string (leer) Eine oder mehrere E-Mail-Adressen, kommagetrennt. Beispiel: webmaster@example.com, seo@example.com.
alerting.thresholdGeo integer (0–100) 0 Alarm, wenn der GEO/SEO-KI-Score einer Seite diesen Wert unterschreitet. 0 deaktiviert den Alarm für diese Kategorie.
alerting.thresholdPerformance integer (0–100) 0 Schwellenwert für den Performance-KI-Score.
alerting.thresholdSemantics integer (0–100) 0 Schwellenwert für den Semantics-KI-Score.
alerting.thresholdKeywords integer (0–100) 0 Schwellenwert für den Keywords-KI-Score.
alerting.thresholdAccessibility integer (0–100) 0 Schwellenwert für den Barrierefreiheits-KI-Score.
alerting.thresholdLighthousePerformance integer (0–100) 0 Schwellenwert für den Lighthouse-Performance-Score.
alerting.thresholdLighthouseAccessibility integer (0–100) 0 Schwellenwert für den Lighthouse-Accessibility-Score.
alerting.thresholdLighthouseBestPractices integer (0–100) 0 Schwellenwert für den Lighthouse-Best-Practices-Score.
alerting.thresholdLighthouseSeo integer (0–100) 0 Schwellenwert für den Lighthouse-SEO-Score.

Empfohlene Scheduler-Konfiguration — nt_ai:alert-check nach den Analyse-Befehlen ausführen, damit aktuelle Daten gelesen werden:

03:00  nt_ai:analyze-pages    (KI-Inhalts-Scores)
03:30  nt_ai:lighthouse       (Lighthouse-PSI-Scores)
04:00  nt_ai:alert-check      (vergleichen + E-Mail senden falls nötig)

Welche Sprache ein Audit abdeckt

Eine Seite wird in der Sprache geprüft, auf die die Aufgabe eingestellt ist — indem für die UID des Satzes in der Standardsprache die URL dieser Sprache gebaut wird. Übersetzte Seitensätze sind deshalb keine eigenen Prüfziele und werden übersprungen: Als eigener Kandidat ergäbe ein solcher Satz den übersetzten Slug ohne Sprachpräfix — etwa /about-us/ statt /en/about-us/ — also eine URL, die es nicht gibt und die nur 404 antworten kann.

Für mehrere Sprachen richtet man je Sprache eine Aufgabe ein, jede mit ihrer eigenen Spracheinstellung. Sie teilen sich die Sperrtabelle und doppeln ihr Wissen über unerreichbare Seiten deshalb nicht.

Bis einschließlich 1.13.1

Übersetzte Sätze wurden als Kandidaten ausgewählt. Jeder von ihnen antwortete 404, belegte damit einen Platz je Lauf und konnte — vor 1.13.0, als die Sperrfrist einen Lauf noch nicht überlebte — den Stapel vollständig füllen. Auf einer zweisprachigen Site betraf das rund die Hälfte aller Kandidaten. Nach dem Update verschwinden sie von selbst aus dem Umlauf; Sperreinträge aus früheren Läufen laufen von allein ab.

Seiten ohne Übersetzung

Ob eine Seite ohne Übersetzung in der Zielsprache 404 antwortet oder die Standardsprache ausliefert, hängt von der Fallback-Einstellung der Site ab. Bei strict antwortet sie 404 und wird als Ergebnis eine Woche zurückgestellt — richtig und unschädlich; mit Fallback wird geprüft, was ausgeliefert wird.

Seiten, die derzeit nicht veröffentlicht sind — verborgen oder außerhalb ihrer Zeitsteuerung — sind ebenfalls keine Kandidaten. Eine Seite mit abgelaufener Endzeit antwortet 404 wie eine verborgene, und anders als eine Seite im Wartungsmodus wird sie nie von selbst wieder prüfbar; eine Seite mit künftigem Startdatum tritt von allein in den Umlauf ein, sobald sie live geht. Eine Seite bewusst vor der Veröffentlichung zu prüfen, ist Aufgabe des signierten Vorschau-Tokens im Backend.

Seiten, die der Audit nicht erreicht

Der geplante Audit arbeitet den Seitenbaum ab, die am längsten nicht geprüfte Seite zuerst. Eine Seite, die nicht abgerufen werden kann, schreibt keinen Bericht — ihr „zuletzt geprüft" bleibt leer, und sie stünde beim nächsten Lauf wieder ganz vorn. Wenige unerreichbare Seiten können so jeden Stapel belegen und den Umlauf zum Stillstand bringen.

Deshalb wird eine solche Seite eine Zeit lang zurückgestellt. Wie lange, hängt von der Antwort des Servers ab:

  • 404 oder 410 — ein beabsichtigtes „nicht gefunden", typischerweise eine Detail-URL ohne Datensatz. Eine Woche Pause: Das ist ein Ergebnis, kein Fehler, und der Inhalt entsteht selten kurzfristig.
  • 503 oder 429 — „vorübergehend nicht verfügbar", also Wartungsseite oder Drosselung. Zurückgestellt für die Zeit, die der Server im Kopffeld Retry-After nennt, sonst eine Stunde. Eine Site im Wartungsmodus braucht damit keine weitere Einstellung: Sie nimmt sich selbst aus dem Umlauf und kehrt zurück, sobald sie wieder da ist.
  • Alles andere (HTTP 5xx, Zeitüberschreitungen, Verbindungsfehler) gilt als technischer Fehler. Die Pause wächst mit jedem weiteren Fehlschlag — 6 Stunden, 24 Stunden, 3 Tage, dann 7 Tage. Ein erfolgreicher Audit löscht den Eintrag.

Nur ein echter technischer Fehler zählt für die Regel, die die Aufgabe rot färbt, wenn jede prüfbare Seite eines Stapels gescheitert ist. Seiten, die lediglich 404 oder 503 geantwortet haben, zählen nicht mit.

Die Einträge stehen in tx_ntai_audit_deferral (eine Zeile je Seite und Sprache, mit Grund und Ende der Pause) und sind damit einsehbar:

SELECT page_uid, status_code, failure_count,
       FROM_UNIXTIME(deferred_until) AS pausiert_bis, reason
FROM tx_ntai_audit_deferral ORDER BY page_uid;

Abgelaufene Einträge werden automatisch entfernt.

Die Spalte reason nennt auch die Herkunft der Frist — Retry-After: 1800s, no Retry-After, default, clean 404/410 oder die Stufe der Fehler-Eskalation. Ohne diese Angabe lässt sich die Frage nicht beantworten: Ein Server mit Retry-After: 3600 und der eingebaute Vorgabewert von einer Stunde ergeben denselben Zeitpunkt.

Vor 1.13.0

Dieser Zustand lag auf dem Objekt der Planer-Aufgabe und konnte einen Lauf nicht überleben: Der Planer speichert eine Aufgabe vor der Ausführung und schreibt danach nur ihre Ausführungsdaten zurück, nie ihre Parameter. Die Pause griff deshalb nie, und ein Stapel unerreichbarer Seiten konnte den Umlauf aushungern. Zu konfigurieren ist nichts — extension:setup muss einmal laufen, damit die neue Tabelle entsteht.

Optionale Argumente in einer Planer-Aufgabe

Eine über das TYPO3-Backend angelegte Aufgabe speichert alle Argumente des Befehls — auch die, die Sie leer gelassen haben: Eine nicht gesetzte pageId wird als leerer String abgelegt, nicht als „nicht vorhanden". nt_ai:analyze-pages und nt_ai:lighthouse behandeln eine leere pageId als „nicht angegeben" und messen dann alle Seiten — das Feld im Backend leer zu lassen tut also das, wonach es aussieht.

Zwei Hinweise dazu:

  • Eine pageId von 0 wird mit einer Fehlermeldung abgewiesen. Seite 0 ist die Baumwurzel und nie eine echte Seite: Sie gehört zu keiner Site und hat keine URL, kann also nur unerreichbare Ergebnisse liefern.
  • Wer Aufgaben per Skript statt über das Backend anlegt, übergibt am besten arguments: [], damit gar keine leeren Werte gespeichert werden.