# Rewrite Rules

Rewrite Rules ermöglichen es dir, eingehende URLs zu transformieren, bevor jegliche andere Verarbeitung stattfindet. Sie funktionieren wie nginx Rewrites und ermöglichen URL-Normalisierung, Legacy-URL-Unterstützung und saubere URL-Strukturen.

### Was sind Rewrite Rules?

Rewrite Rules modifizieren die Anfrage-URL basierend auf einem URL-Abgleich. Sie werden früh im Anfrageablauf ausgewertet, direkt nach Access Rules und vor Page Rules, wodurch URL-Transformationen stattfinden, bevor Konfigurationsregeln die URL auswerten.

**Wichtige Eigenschaften:**

* Werden **als zweites** in der Regelsequenz ausgeführt (nach Access Rules, vor Page und Conditional Rules)
* Transformieren URLs vor der Cache-Abfrage
* nginx-artige URL-Umschreibung
* Werden in **Positionsreihenfolge** ausgewertet (1, 2, 3...)
* **Stopp nach erstem Treffer** – sobald eine Regel zutrifft, werden keine weiteren Rewrite Rules ausgewertet

### Wie Rewrite Rules funktionieren

Rewrite Rules werden in aufsteigender Positionsreihenfolge (1 → 2 → 3...) für jede eingehende Anfrage ausgewertet. Wenn das URL-Muster einer Regel zutrifft, wird die URL zum Zielpfad umgeschrieben und die Auswertung stoppt.

#### Positionsbasierte Auswertung

```
Anfrage: /alter-pfad
    ↓
Rewrite Rule (Position 1) → Treffer /alter-pfad? → Umschreiben zu /neuer-pfad → STOPP
    ↓ (kein Treffer)
Rewrite Rule (Position 2) → Treffer? → Umschreiben → STOPP
    ↓ (kein Treffer)
Weiter zu Page Rules mit originaler oder umgeschriebener URL...
```

**Wichtig:** Sobald eine Rewrite Rule zutrifft, werden keine weiteren Rewrite Rules ausgewertet. Die umgeschriebene URL wird dann von allen nachfolgenden Regeln (Page Rules, Conditional Rules) verwendet.

### URL-Abgleich

Rewrite Rules verwenden das gleiche URL-Abgleichsystem wie Page Rules. Du kannst URLs mit drei verschiedenen Matchern abgleichen:

#### Matcher

**Equals (`=`)**: Exakter Treffer

```
Matcher: Equals
URL: /alte-seite
Ziel: /neue-seite

Trifft zu: /alte-seite
Trifft nicht zu: /alte-seite/, /alte-seite?query=1, /alte-seite-extra
```

**Matches Regex (`~`)**: Groß-/Kleinschreibung-sensitiver Regex

```
Matcher: Matches Regex
URL: ^/blog/(\d+)
Ziel: /artikel/$1

Trifft zu: /blog/123 → /artikel/123
Trifft nicht zu: /BLOG/123 (Groß-/Kleinschreibung-sensitiv)
```

**Matches Regex Case-Insensitive (`~*`)**: Groß-/Kleinschreibung-ignorierender Regex

```
Matcher: Matches Regex Case-Insensitive
URL: ^/produkte/(.*)
Ziel: /shop/$1

Trifft zu: /produkte/artikel → /shop/artikel
Trifft auch zu: /PRODUKTE/artikel → /shop/artikel
```

#### URL vs URI

* **URL**: Die vollständige Webadresse inklusive Protokoll und Domain
  * Beispiel: `https://www.beispiel.de/kategorie/daten.html`
* **URI**: Nur der Pfad ohne Domain oder Protokoll
  * Beispiel: `/kategorie/daten.html`

Rewrite Rules arbeiten mit **URIs** (nur der Pfad).

### Wann Rewrite Rules verwenden

#### Verwende Rewrite Rules wenn:

* ✅ Du **Legacy-URLs unterstützen** musst, während du deine Website umstrukturierst
* ✅ Du **saubere, SEO-freundliche URLs** möchtest (z.B. `/produkt/123` statt `/produkt.php?id=123`)
* ✅ Du **von einer anderen Plattform migrierst** und alte URL-Strukturen beibehalten musst
* ✅ Du **URL-Normalisierung** benötigst (z.B. Trailing-Slashes entfernen, URLs kleinschreiben)
* ✅ URL-Transformationen **vor** der Auswertung anderer Regeln stattfinden sollen

### Anwendungsfälle & Beispiele

#### Beispiel 1: Legacy-URL-Unterstützung

**Szenario:** Du hast deine Website von `/alter-bereich/seite.html` zu `/neuer-bereich/seite` umstrukturiert, musst aber alte Links unterstützen.

```
Position: 1
Matcher: Matches Regex
URL: ^/alter-bereich/(.*)\.html$
Ziel: /neuer-bereich/$1

Ergebnis:
/alter-bereich/ueber-uns.html → /neuer-bereich/ueber-uns
/alter-bereich/kontakt.html → /neuer-bereich/kontakt
```

**Warum umschreiben statt weiterleiten?** Umschreibungen sind transparent – der Benutzer sieht keine URL-Änderung, und du behältst den ursprünglichen Anfragekontext. Page Rules können dann Konfigurationen basierend auf der neuen URL anwenden.

#### Beispiel 2: Saubere URL-Struktur

**Szenario:** Deine Anwendung verwendet Query-Parameter, aber du möchtest saubere URLs für SEO.

```
Position: 1
Matcher: Matches Regex
URL: ^/produkt/([0-9]+)$
Ziel: /produkt.php?id=$1

Ergebnis:
/produkt/12345 → /produkt.php?id=12345
(Saubere URL wird zur tatsächlichen Backend-URL umgeschrieben)
```

**Warum das funktioniert:** Benutzer und Suchmaschinen sehen saubere URLs (`/produkt/12345`), aber dein Backend erhält das Query-Parameter-Format, das es erwartet.

#### Beispiel 3: Plattform-Migration

**Szenario:** Migration von WordPress zu einer neuen Plattform, wobei alte Post-URLs unterstützt werden müssen.

```
Position: 1
Matcher: Matches Regex
URL: ^/([0-9]{4})/([0-9]{2})/(.*)$
Ziel: /posts/$1-$2-$3

Ergebnis:
/2024/03/mein-blog-post → /posts/2024-03-mein-blog-post
/2023/12/ein-anderer-post → /posts/2023-12-ein-anderer-post
```

**Kombiniert mit Page Rules:** Nach dem Umschreiben kann eine Page Rule, die `/posts/*` matched, spezifische Caching- oder Optimierungseinstellungen anwenden.

### Zielpfad

Der **Zielpfad** ist das Ziel, zu dem die URL umgeschrieben wird. Er kann sein:

* **Statischer Pfad**: `/neuer-ort`
* **Mit Capture-Groups**: `/bereich/$1` (verwendet Regex-Capture-Groups aus dem URL-Muster)
* **Mehrere Captures**: `/kategorie/$1/artikel/$2`

**Wichtig:** Der Zielpfad ist der tatsächliche Backend-Pfad, den deine Anwendung erhält. Stelle sicher, dass es ein gültiger Pfad ist, den deine Anwendung verarbeiten kann.

### Best Practices für die Regelreihenfolge

Da Rewrite Rules beim ersten Treffer stoppen, ordne sie sorgfältig an:

#### 1. Spezifischste zuerst

```
Position 1: /exakt/spezifischer/pfad → /ziel1
Position 2: /spezifisch/* → /ziel2
Position 3: /* → /ziel3
```

#### 2. Exakte Treffer vor Mustern

```
Position 1: = /spezial-seite → /neue-spezial
Position 2: ~ ^/spezial → /regulaer-spezial
```

#### 3. Nachfolgende Regeln bedenken

Denke daran, dass Page Rules und Conditional Rules gegen die **umgeschriebene** URL auswerten, nicht die originale:

```
Rewrite Rule: /alt/* → /neu/*
Page Rule: Match /neu/* (nicht /alt/*)
```

#### 4. Ähnliche Muster zusammenfassen

Verwende Regex, um mehrere Fälle effizient zu behandeln:

```
❌ Weniger effizient (mehrere Regeln):
/alt-ueber-uns → /ueber-uns
/alt-kontakt → /kontakt
/alt-hilfe → /hilfe

✅ Effizienter (eine Regel):
^/alt-(.*)$ → /$1
```

**Verwende Regex für Flexibilität:**

```
❌ Mehrere spezifische Regeln:
/produkt-1 → /artikel/1
/produkt-2 → /artikel/2
...

✅ Eine flexible Regel:
^/produkt-([0-9]+)$ → /artikel/$1
```

### Eindeutigkeit

Jede Website muss eindeutige haben:

* **Regelnamen** – jede Regel muss einen eindeutigen Namen haben
* **URL-Muster** – du kannst keine doppelten URL-Muster haben

Wenn du versuchst, ein Duplikat zu erstellen, siehst du: "Name existiert bereits" oder "Gleicher Matcher existiert."

### Häufige Fehler

❌ **Catch-all-Umschreibung auf Position 1**

```
Position 1: ~ ^/(.*)$ → /neu/$1
→ Schreibt ALLES um, andere Regeln treffen nie zu
```

✅ **Spezifische Muster zuerst**

```
Position 1: = /spezial → /neu-spezial
Position 2: ~ ^/blog/(.*)$ → /artikel/$1
Position 3: ~ ^/alt-(.*)$ → /$1
```

***

❌ **Page Rules vergessen**

```
Rewrite Rule: /alt-admin → /admin
Page Rule: Match /alt-admin/* → TRIFFT NIE ZU
Sollte matchen: /admin/*
```

✅ **Page Rules matchen umgeschriebene URLs**

```
Rewrite Rule: /alt-admin → /admin
Page Rule: Match /admin/* → Trifft nach Umschreibung zu
```

***

❌ **Ungültiger Zielpfad**

```
URL: ^/produkt/(.*)$
Ziel: /ungueltig/$2 (Capture-Group $2 existiert nicht)
→ Fehlerhafte Umschreibung
```

✅ **Gültige Capture-Groups**

```
URL: ^/produkt/(.*)$
Ziel: /artikel/$1 (verwendet Capture-Group $1)
```

### Rewrite Rules testen

1. **Aktiviere Debug-Header** in deiner Website-Konfiguration
2. **Führe Testanfragen** mit den originalen URLs durch
3. **Prüfe die Response-Header** um zu sehen, welche Regeln angewendet wurden und wie die URL wurde
4. **Verifiziere, dass Page Rules** die umgeschriebene URL matchen, nicht die originale
