Weiterleitungen und 404-Protokoll
Weiterleitungen leiten tote URLs einer Website auf bestehende um. Sie greifen nur, wo sonst die 404-Seite käme – also bei Pfaden ohne Seite und bei unbekannten Unterpfaden einer Catch-All-Seite (not_found()). Vorhandene Seiten haben immer Vorrang.
- Pfade werden normalisiert: dekodiert, klein geschrieben, ohne Query und ohne Schrägstrich am Ende. Eine eingefügte URL (
https://alt.de/Seite/?x=1) wird zu/seite. Query-Parameter des Aufrufs hängen am Ziel, wenn das Ziel selbst keine hat. - Antwort:
301(mitCache-Control: max-age=3600, damit geänderte Weiterleitungen nicht ewig im Browser hängen) oder302(no-store). - Automatisch: Wird eine veröffentlichte Seite umbenannt (Slug) oder innerhalb ihrer Website verschoben, entstehen 301-Weiterleitungen für sie und ihre veröffentlichten Unterseiten (
auto: true). Weiterleitungen, die auf den alten Pfad zeigten, zeigen danach direkt auf den neuen; eine Weiterleitung von einem wieder belegten Pfad wird entfernt. - 404-Protokoll: Aufrufe toter URLs ohne Weiterleitung (nur
GET) werden je Website gezählt – mit erstem/letztem Aufruf und der zuletzt gesehenen Herkunft (Referer), höchstens 1.000 Einträge je Website. Das Anlegen einer Weiterleitung nimmt den Pfad aus dem Protokoll. - Bundles enthalten die Weiterleitungen, nicht das 404-Protokoll.
Weiterleitungs-Objekt
{
"id": 4, "root_id": 1,
"source": "/blog/123",
"target": "/blog/mein-artikel",
"status": 301, "auto": false,
"hits": 12, "last_hit_at": 1791220210, "created_at": 1791220100,
"target_missing": false
}
| Feld | Typ | Beschreibung |
|---|---|---|
root_id |
int | Website (Root-Seite); beim Ändern nicht änderbar |
source |
string | Alte Adresse (Pfad oder URL, wird normalisiert). Nicht /, nicht unter /cms-admin, /api, /media, /_assets, /sitemap.xml, /healthz, /favicon.ico, /robots.txt und nicht der Pfad einer bestehenden Seite (400). Je Website eindeutig (409) |
target |
string | Pfad (/neu) oder http(s)-URL. Keine Schleifen über andere Weiterleitungen (400) |
status |
int | 301 (Standard) oder 302 |
auto |
bool | Nur lesend: automatisch beim Umbenennen/Verschieben angelegt (wird beim Bearbeiten false) |
hits, last_hit_at |
int | Nur lesend: Nutzung |
target_missing |
bool | Nur in der Liste: das Ziel ist ein Pfad ohne Seite und ohne weitere Weiterleitung |
GET /redirects?root_id={id} 🔑
Alle Weiterleitungen der Website, nach Pfad sortiert.
POST /redirects ✏️ · PUT /redirects/{id} ✏️ · DELETE /redirects/{id} ✏️
{ "root_id": 1, "source": "/blog/123", "target": "/blog/mein-artikel", "status": 301 }
POST → 201, PUT (Merge, source/target/status) → 200, DELETE → 204.
GET /notfound?root_id={id} 🔑 · DELETE /notfound?root_id={id}[&path=…] ✏️
404-Protokoll der Website, häufigste zuerst: [{ "path": "/angebote/2019", "hits": 7, "first_at": …, "last_at": …, "referer": "https://www.example.org/links" }]. Jeder Eintrag trägt ignored (true = ausgeblendet; zählt weiter, steht aber nicht im CSV-Export). PUT mit Body { "ignored": true|false } blendet einen Eintrag (path) aus bzw. wieder ein; ohne path alle offenen (true) bzw. alle ignorierten (false) – 204, der Eintrag bleibt samt Zähler erhalten. DELETE entfernt einen Eintrag (path) oder das ganze Protokoll endgültig. Das Protokoll hält höchstens 1000 offene und 5000 ignorierte Adressen je Website (die am längsten nicht mehr gesehenen fallen heraus).
GET /redirects/export?root_id={id} 🔑
CSV (UTF-8 mit BOM, Trennzeichen Semikolon) mit den Spalten Von;Nach;Status;Typ;Treffer;Zuletzt;Herkunft: zuerst die offenen Adressen aus dem 404-Protokoll (häufigste zuerst, Nach und Status leer, Typ = 404), danach alle Weiterleitungen (Typ = manuell oder auto). Zuletzt als JJJJ-MM-TT HH:MM (Serverzeit).
POST /redirects/import?root_id={id}[&dry_run=1][&delete=1] ✏️
Multipart-Feld file: CSV (UTF-8, optional mit BOM; Trennzeichen Komma, Semikolon oder Tab wird erkannt). Spalten werden über die Kopfzeile erkannt: Von (auch source, from, alt, pfad …) und Nach (auch target, to, ziel …) sind Pflicht, Status (301/302, leer = bisheriger Status bzw. 301) optional, alle weiteren werden ignoriert. Abgeglichen wird über den normalisierten Pfad in Von:
- Zeile mit Ziel → neue Weiterleitung oder Änderung von Ziel/Status (gilt danach als manuell); unveränderte zählen als
unchanged. Neue nehmen ihren Pfad aus dem 404-Protokoll. - Zeile ohne Ziel → bleibt offen (
open); eine bestehende Weiterleitung bleibt unverändert. delete=1: Weiterleitungen, die in der Datei fehlen oder dort kein Ziel haben, werden gelöscht.
Geprüft wird wie bei POST /redirects – Schleifen auch über mehrere Zeilen der Datei –, dazu doppelte Pfade. Alles oder nichts: bei Fehlern 422 (mit error, code csv.errors und params.count), nichts wird geschrieben. dry_run=1 liefert nur die Vorschau (200, auch bei Fehlern):
{ "delimiter": ";", "rows": 4, "created": 1, "updated": 1, "deleted": 0, "unchanged": 1, "open": 1,
"changes": [{ "action": "create", "source": "/kaputt", "target": "/neu", "status": 301 },
{ "action": "update", "source": "/weg", "target": "https://example.com/", "status": 301, "old_target": "/neu", "old_status": 302 }],
"errors": [{ "row": 3, "message": "this redirect would create a loop", "code": "redirect.loop" }], "error_count": 1, "imported": false }
row zählt die Kopfzeile als Zeile 1; errors enthält höchstens 50 Einträge.