URLs wie beispiel.de/kontakt.html oder beispiel.de/produkte.php sind ein Relikt aus der Frühzeit des Webs. Damals entsprach jede URL einer echten Datei auf dem Server, und die Endung verriet dem Browser, was er zu erwarten hatte. Heute wirken Dateiendungen in URLs unprofessionell und sind für SEO ein Nachteil - saubere URLs wie beispiel.de/kontakt/ sind kürzer, einprägsamer und werden von Suchmaschinen bevorzugt.
Das Entfernen der Dateiendung ist mit einer .htaccess-Regel in wenigen Minuten erledigt. Der Server liefert die Datei weiterhin aus, aber die URL im Browser zeigt keine Endung mehr. Bestehende Links und Suchmaschinen-Rankings werden per 301-Redirect auf die neue URL übertragen.
.html-Endung entfernen
Die häufigste Anforderung: Aus /seite.html soll /seite/ werden. Dafür brauchst du zwei Regeln in der .htaccess - eine für den Redirect (damit alte Links weitergeleitet werden) und eine für das interne Rewriting (damit der Server die Datei trotzdem findet).
RewriteEngine On
# Schritt 1: .html-Aufrufe per 301 auf saubere URL umleiten
RewriteCond %{THE_REQUEST} \s/(.+?)\.html[\s?] [NC]
RewriteRule ^ /%1/ [R=301,L]
# Schritt 2: Saubere URL intern auf .html-Datei mappen
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/$1.html -f
RewriteRule ^(.+?)/?$ /$1.html [L]
Schritt 1 fängt alle Aufrufe mit .html ab und leitet sie per 301 auf die Version ohne Endung um. Der Trick mit %{THE_REQUEST} statt %{REQUEST_URI} ist wichtig - er verhindert eine Endlosschleife, weil THE_REQUEST den Original-Request enthält und sich durch internes Rewriting nicht ändert.
Schritt 2 sorgt dafür, dass der Server bei einem Aufruf von /seite/ intern die Datei seite.html ausliefert. Die Bedingungen prüfen, dass es kein echtes Verzeichnis und keine echte Datei mit diesem Namen gibt, und dass die .html-Datei tatsächlich existiert.
RewriteRule ^(.*)\.html$ /$1/ [R=301,L]. Die funktioniert in manchen Konfigurationen, erzeugt aber auf vielen Servern eine Endlosschleife (Error 500), weil der intern umgeschriebene Request erneut auf die Redirect-Regel trifft. Die Lösung mit %{THE_REQUEST} verhindert das zuverlässig.
.php-Endung entfernen
Das gleiche Prinzip funktioniert auch für PHP-Dateien. Aus /kontakt.php wird /kontakt/:
RewriteEngine On
# .php-Aufrufe per 301 umleiten
RewriteCond %{THE_REQUEST} \s/(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1/ [R=301,L]
# Saubere URL intern auf .php-Datei mappen
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.+?)/?$ /$1.php [L]
Der Code ist identisch, nur mit .php statt .html. Du kannst beide Regelsets in derselben .htaccess kombinieren. Die Redirect-Regeln sollten vor den Rewrite-Regeln stehen.
Beide Endungen gleichzeitig entfernen
Wenn du sowohl .html als auch .php loswerden willst, lassen sich die Regeln zusammenfassen:
RewriteEngine On
# .html und .php per 301 umleiten
RewriteCond %{THE_REQUEST} \s/(.+?)\.(html|php)[\s?] [NC]
RewriteRule ^ /%1/ [R=301,L]
# Intern auflösen: erst .php, dann .html versuchen
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.+?)/?$ /$1.php [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/$1.html -f
RewriteRule ^(.+?)/?$ /$1.html [L]
Die Regex (html|php) matcht beide Endungen in einer Regel. Beim internen Rewriting wird zuerst nach einer .php-Datei gesucht, dann nach .html. Falls beides existiert, gewinnt PHP - was in der Praxis fast immer das gewünschte Verhalten ist.
Was passiert mit Query-Parametern?
Wenn deine alten URLs Parameter enthalten (z.B. /suche.php?q=test), werden diese automatisch mit übernommen. Die RewriteRule leitet auf /suche/?q=test um. Die Parameter gehen nicht verloren, weil Apache sie standardmässig durchreicht.
Falls du die Parameter explizit entfernen willst (z.B. weil sie nicht mehr gebraucht werden), hänge ein ? an die Ziel-URL an:
RewriteRule ^ /%1/? [R=301,L]
Das leere Fragezeichen am Ende löscht alle bestehenden Query-Parameter.
Nginx: Dateiendung entfernen
Auf Nginx gibt es keine .htaccess. Die Regeln werden in der Server-Konfiguration definiert:
# .html-Endung entfernen
if ($request_uri ~ ^/(.+)\.html$) {
return 301 /$1/;
}
# Saubere URLs intern auf Dateien mappen
try_files $uri $uri/ $uri.html $uri.php =404;
Die try_files-Direktive ist das Nginx-Pendant zum internen Rewriting. Sie probiert der Reihe nach verschiedene Dateipfade durch, bis einer existiert.
SEO: Warum saubere URLs wichtig sind
Saubere URLs ohne Dateiendung haben mehrere Vorteile. Sie sind kürzer und damit einfacher zu merken, zu teilen und auf Visitenkarten zu drucken. Suchmaschinen behandeln sie nicht anders als URLs mit Endung - der direkte Ranking-Vorteil ist also gering. Der indirekte Vorteil ist aber real: Saubere URLs werden häufiger geklickt, weil sie vertrauenswürdiger aussehen. Eine URL wie /kontakt/ wirkt professioneller als /kontakt.php.
Der 301-Redirect sorgt dafür, dass bestehende Rankings und Backlinks nicht verloren gehen. Suchmaschinen übertragen die Ranking-Signale von der alten auf die neue URL. Das passiert nicht sofort, aber innerhalb weniger Wochen. Wichtig: Verwende immer 301 (permanent) und nicht 302 (temporär), sonst behält Google die alte URL im Index. Mehr dazu im Artikel PHP Redirect 301.
Typische Probleme
Endlosschleife (Error 500)
Passiert wenn die Redirect-Regel auf den intern umgeschriebenen Request erneut greift. Lösung: %{THE_REQUEST} statt %{REQUEST_URI} in der RewriteCond verwenden (siehe Code oben).
CSS und Bilder laden nicht mehr
Wenn nach dem Entfernen der Endung Stylesheets und Bilder fehlen, liegt es an relativen Pfaden. Eine URL wie /verzeichnis/seite/ wird vom Browser als Verzeichnis interpretiert - relative Pfade wie style.css zeigen dann auf /verzeichnis/seite/style.css statt /style.css. Lösung: Verwende absolute Pfade (mit / am Anfang) oder setze ein <base href="/"> im HTML-Head.
Trailing Slash ja oder nein?
Die Beispiele oben leiten auf URLs mit Trailing Slash um (/seite/). Du kannst auch ohne Slash arbeiten (/seite). Wichtig ist nur, dass du dich für eine Variante entscheidest und die andere per 301 umleitest. Mischungen führen zu Duplicate Content. Mehr dazu im Artikel Slash am Ende der URL.
Häufige Fragen
Muss ich alle internen Links anpassen?
Nicht zwingend. Der 301-Redirect fängt die alten URLs ab. Aber sauberer ist es, die internen Links gleich auf die neue URL umzustellen - das spart einen Redirect pro Klick und ist minimal schneller.
Funktioniert das auch mit WordPress?
WordPress verwendet standardmässig bereits saubere URLs (Permalinks). Die .html-Endung ist dort nur aktiv, wenn sie in den Permalink-Einstellungen explizit konfiguriert wurde. Zum Entfernen: Unter Einstellungen > Permalinks eine Struktur ohne .html wählen (z.B. "Beitragsname") und die .htaccess-Redirect-Regel für die alten .html-URLs hinzufügen.
Was ist mit index.html und index.php?
Index-Dateien brauchst du nicht umzuleiten. Apache liefert index.html bzw. index.php automatisch aus, wenn ein Verzeichnis aufgerufen wird. Die Regeln oben schliessen Verzeichnisse über die Bedingung !-d bereits aus.
Kommentararchiv 2
Leser wiesen auf einen Fehler in der ursprünglichen RewriteRule hin: Der Slash zwischen Domain und Pfad fehlte, was zu einer fehlerhaften Weiterleitung führte. Ausserdem funktionierte die Regel nur mit absoluten URLs korrekt, nicht mit relativen Pfaden. Beide Hinweise sind in der aktuellen Version des Artikels berücksichtigt.