Was ist die History-API?

Die History-API lässt JavaScript URL und Zurück-Taste ändern, ohne neu zu laden. So funktionieren pushState, replaceState, popstate, plus SEO-Fallen.

Was ist die History-API?

Die History-API ist eine Browser-Schnittstelle, erreichbar über window.history, mit der JavaScript durch den Sitzungsverlauf navigieren und Einträge hinzufügen oder ändern kann. Mit pushState() und replaceState() kann eine Seite Adressleiste und Zurück-Taste aktualisieren, ohne neu zu laden. So gibt eine Single-Page-Anwendung jedem Bildschirm eine eigene URL.

So funktioniert sie

  • history.back(), history.forward() und history.go(n) bewegen sich durch vorhandene Einträge, wie die Browser-Schaltflächen. history.length ist die Anzahl der Einträge.
  • history.pushState(state, "", url) fügt einen neuen Eintrag hinzu. history.replaceState(state, "", url) überschreibt stattdessen den aktuellen.
  • state ist ein beliebiges serialisierbares Objekt, das mit dem Eintrag gespeichert wird. Das zweite Argument wird nicht verwendet, darf aber nicht fehlen: Übergeben Sie einen leeren String.
  • url ist optional und muss denselben Origin wie die aktuelle Seite haben, sonst wirft der Aufruf einen SecurityError.
  • Keine der Methoden lädt die URL oder prüft, ob sie existiert. Sie ändern nur, was der Browser aufzeichnet und anzeigt.
  • Das Event popstate wird ausgelöst, wenn der Nutzer durch den Verlauf navigiert (Zurück, Vor, go()). pushState() und replaceState() lösen es nicht aus, und Browser feuern es unter Umständen erst, wenn mit der Seite interagiert wurde.

Die Details dokumentiert die MDN-Referenz zu pushState().

Ein minimaler Router

Die Navigation ruft pushState auf und rendert die Ansicht selbst. Zurück und Vor lösen popstate aus, und der Handler rendert die Ansicht für die vom Browser wiederhergestellte URL:

function navigate(path) {
  history.pushState({ path: path }, "", path);
  render(path);
}

window.addEventListener("popstate", function () {
  render(location.pathname);
});

Das Rendern arbeitet direkt am DOM, es wird also kein neues Dokument angefordert.

Der Server muss diese URLs trotzdem beantworten

Eine mit pushState erzeugte URL ist nur ein Eintrag im Browser. Lädt ein Besucher auf /products/42 neu, setzt ein Lesezeichen oder folgt einem geteilten Link, erhält der Server diese Anfrage. Er muss dafür die App (oder echten Inhalt) liefern, keinen 404. Laut MDN lädt der Browser die URL nach pushState() nicht, kann sie aber später laden, etwa nach einem Neustart.

SEO und Crawler

Googles Empfehlung für JavaScript-Websites lautet, die History-API für das Routing zwischen Ansichten zu verwenden und keine URL-Fragmente zu nutzen, um unterschiedliche Inhalte zu laden. Links müssen echte <a href="...">-Elemente sein: Crawler finden Links über das href, und ein Klick-Handler auf einem span oder ein Anker ohne href gibt ihnen nichts zum Folgen. Auch Fehleransichten brauchen Sorgfalt, denn eine clientseitig geroutete 404-Seite liefert weiterhin Status 200, solange Sie nicht auf eine URL mit echtem 404 weiterleiten oder ein noindex-Robots-Tag setzen. Siehe Googles Grundlagen zu JavaScript-SEO.

Häufige Fehler

  • Kein popstate-Handler. Die URL ändert sich bei Zurück, die Ansicht aber nicht.
  • Links ohne href. Sie funktionieren im Browser und sind für Crawler unsichtbar; Mittelklick und "In neuem Tab öffnen" gehen nicht.
  • Hash-Routing für Inhalte. Fragment-URLs lösen Crawler nicht zuverlässig auf.
  • Große State-Objekte. Manche Browser begrenzen die serialisierte Größe und werfen einen Fehler. Halten Sie den State klein und nutzen Sie für mehr sessionStorage.
  • Erwarten, dass sich der Titel ändert. Das zweite Argument wird ignoriert; setzen Sie document.title selbst und setzen Sie den Fokus für Screenreader-Nutzer.
  • Kein Server-Fallback. Deep Links liefern beim Neuladen einen 404.

Bezug zu Tests und Überwachung

Eine pushState-Navigation fordert in der Regel keine neue HTML-Seite an. Die Kosten stecken in den API-Aufrufen und dem Rendern danach, ein Test, der nur HTML abruft, verpasst das meiste. Testen Sie die API-Aufrufe der App, gewichtet so, wie Nutzer sie auslösen: siehe Lasttests für Single-Page-Anwendungen, ausführbar mit Lasttests. Das API-Monitoring überwacht weiter die Endpunkte hinter Ihren Routen, und Synthetic Monitoring deckt ganze Abläufe ab. Prüfen Sie tiefe URLs außerdem direkt: Eine Anfrage an eine Routen-URL sollte vom Server 200 liefern und nicht nur nach In-App-Navigation funktionieren.

Häufige Fragen: History-API

Lädt pushState die Seite neu?

Nein. Es fügt einen Verlaufseintrag hinzu und ändert die in der Adressleiste angezeigte URL, aber der Browser lädt diese URL nicht und prüft nicht, ob sie existiert.

Löst pushState das popstate-Event aus?

Nein. popstate wird ausgelöst, wenn sich der aktive Verlaufseintrag durch Nutzernavigation ändert, etwa Zurück, Vor oder history.go(). Nach Ihrem eigenen pushState-Aufruf aktualisieren Sie die Ansicht selbst.

Was ist der Unterschied zwischen pushState und replaceState?

pushState fügt einen neuen Eintrag hinzu, sodass Zurück zum vorherigen führt. replaceState überschreibt den aktuellen Eintrag, es entsteht also kein zusätzlicher Zurück-Schritt. Nutzen Sie replace für Korrekturen wie Weiterleitungen oder das Aktualisieren eines Filters in der URL.

Hash-Routing oder History-API?

Für Inhalte, die indexiert werden sollen, nutzen Sie die History-API mit echten Pfaden. Google rät davon ab, URL-Fragmente zum Laden unterschiedlicher Inhalte zu verwenden. Hash-Routing braucht keine Serverkonfiguration, was für interne Werkzeuge ohne Suchverkehr passen kann.

Brauche ich Serverkonfiguration für History-API-Routen?

Ja. Der Server muss jede Routen-URL beantworten, meist mit dem App-Grundgerüst oder vorgerendertem Inhalt, denn Neuladen, Lesezeichen oder geteilte Links fordern genau diese URL direkt an.

Wie schnell ist Ihre Website?

Steigern Sie ihre Geschwindigkeit und SEO nahtlos mit unserem kostenlosen Geschwindigkeitstest.

Kostenloser Websitespeed-Test

Analysieren Sie die Ladegeschwindigkeit Ihrer Website und verbessern Sie ihre Leistung mit unserem kostenlosen Seitengeschwindigkeits-Checker.