Signatur
Beschreibung
Das Navigation-Interface ist der Kern der Navigation API und ersetzt in modernen Anwendungen die umständliche Kombination aus History-API, popstate und abgefangenen Link-Klicks. Es gibt genau eine Instanz pro Fenster. Du erreichst sie über window.navigation. Über dieses Objekt kannst du Navigationen starten (navigate(), reload(), back(), forward(), traverseTo()), die Verlaufseinträge des eigenen Ursprungs auslesen (entries(), currentEntry) und auf jede Navigation reagieren.
Besonders wichtig für Single-Page-Anwendungen ist das Ereignis navigate. Es wird bei jeder Navigation ausgelöst, egal ob durch einen Link-Klick, ein Formular, die Zurück-/Vor-Schaltflächen oder programmatisch. Mit event.intercept({ handler }) wandelst du eine normale Dokumentnavigation in eine Navigation innerhalb des Dokuments um. So lässt sich clientseitiges Routing an einer einzigen Stelle umsetzen.
Wichtige Mitglieder:
- Eigenschaften:
currentEntry(NavigationHistoryEntry),transition(NavigationTransition | null),activation,canGoBack,canGoForward. - Methoden:
entries(),navigate(url, options),reload(options),back(options),forward(options),traverseTo(key, options),updateCurrentEntry({ state }). - Ereignisse:
navigate,navigatesuccess,navigateerror,currententrychange.
Die Navigationsmethoden geben ein Objekt { committed, finished } mit zwei Promises zurück. committed wird erfüllt, sobald sich die sichtbare URL geändert hat. finished wird erfüllt, sobald alle über intercept() registrierten Handler abgeschlossen sind.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $url Pflicht | string | Nur für navigate(): Ziel-URL, absolut oder relativ zum aktuellen Dokument. |
|
| $options.state | any | undefined | Für navigate(), reload() und updateCurrentEntry(): strukturiert klonbarer Zustand, der am Verlaufseintrag gespeichert wird. Du liest ihn mit entry.getState() aus. |
| $options.info | any | undefined | Flüchtige Zusatzinfo, die nur an das navigate-Ereignis (event.info) übergeben und nicht gespeichert wird, z. B. die gewünschte Animationsrichtung. |
| $options.history | "auto" | "push" | "replace" | "auto" | Nur für navigate(): legt fest, ob ein neuer Verlaufseintrag angelegt oder der aktuelle ersetzt wird. |
| $key Pflicht | string | Nur für traverseTo(): der key eines NavigationHistoryEntry, zu dem gesprungen werden soll. |
Rückgabewert
navigate, reload, back, forward, traverseTo) geben ein Objekt mit zwei Promises zurück. Bei Abbruch oder Fehler werden beide mit einer DOMException zurückgewiesen, etwa AbortError oder InvalidStateError.Beispiele
Zugriff und Feature-Erkennung
if ('navigation' in window) {
const nav = window.navigation;
console.log(nav.currentEntry.url);
console.log('Einträge:', nav.entries().length);
console.log('Zurück möglich:', nav.canGoBack);
} else {
console.log('Navigation API nicht verfügbar – Fallback auf History API');
}
Clientseitiges Routing mit navigate + intercept
const routes = {
'/': () => '<h1>Start</h1>',
'/kontakt': () => '<h1>Kontakt</h1>'
};
navigation.addEventListener('navigate', (event) => {
// Nur gleiche Herkunft, keine Downloads, keine Hash-Sprünge
if (!event.canIntercept || event.hashChange || event.downloadRequest) return;
const url = new URL(event.destination.url);
const render = routes[url.pathname];
if (!render) return; // normale Navigation zulassen
event.intercept({
async handler() {
document.querySelector('main').innerHTML = render();
}
});
});
navigation.addEventListener('navigatesuccess', () => {
console.log('Navigation fertig:', location.pathname);
});
Programmatisch navigieren und Zustand speichern
const openProduct = async (id) => {
const { committed, finished } = navigation.navigate(`/produkt/${id}`, {
state: { scrollY: window.scrollY },
info: { animation: 'slide-left' }
});
await committed; // URL ist bereits geändert
const entry = await finished; // alle Handler abgeschlossen
console.log(entry.url, entry.getState());
};
openProduct(42).catch((err) => console.error('Abgebrochen:', err.name));
Zu einem bestimmten Verlaufseintrag springen
const home = navigation.entries().find(
(entry) => new URL(entry.url).pathname === '/'
);
if (home) {
await navigation.traverseTo(home.key).finished;
} else {
await navigation.navigate('/', { history: 'replace' }).finished;
}
navigation.addEventListener('currententrychange', (e) => {
console.log('Vorher:', e.from.url, 'Typ:', e.navigationType);
});
// Wichtig · Fallstricke
Browser-Kompatibilität: Chromium-Browser unterstützen die API seit Version 102 (2022). In Firefox und Safari ist sie erst seit Ende 2025 bzw. Anfang 2026 verfügbar. Prüfe sie daher immer per Feature-Erkennung mit 'navigation' in window und sieh für ältere Browser einen Fallback über die History-API vor.
entries()liefert nur Einträge desselben Ursprungs innerhalb der aktuellen Sitzung, keine fremden Seiten.intercept()funktioniert nur, wennevent.canIntercepttrueist. Bei ursprungsübergreifenden Zielen ist das nicht der Fall.- Traversierungen, also Zurück und Vor, lassen sich nicht mit
event.preventDefault()abbrechen, sofern sie nicht vom eigenen Dokument ausgelöst wurden. Prüfe dazuevent.cancelable. - Wenn du nur auf
finishedreagierst, führt eine unterbrochene Navigation (AbortError) ohnecatchzu unbehandelten Promise-Zurückweisungen. - Der in
stategespeicherte Zustand muss strukturiert klonbar sein. Funktionen und DOM-Knoten führen zu einemDataCloneError. - Sicherheit: Wenn du Inhalte aus URL-Parametern per
innerHTMLrenderst, droht XSS. Bereinige Daten ausevent.destination.urlimmer, bevor du sie ausgibst.