APIs de la web, hoyLaboratorio · Alex Harto

Navigation API

Un solo evento para todas las navegaciones: el router estándar que sustituye a pushState y popstate.

En tu navegador: comprobando…Revisado 1 oct 2026

navigation.addEventListener('navigate') recibe enlaces, formularios, atrás y adelante, recargas y cambios de location. Con event.intercept() la página decide qué pintar sin recargar, y el navegador lleva el historial, el foco y el scroll.

Es Baseline desde el 13 de enero de 2026 (Firefox 147, con Safari 26.2 un mes antes). precommitHandler, para redirigir o cancelar antes de que cambie la URL, está en Chrome 141 y Firefox 147, y forma parte de Interop 2026.

Para qué sirve

  • Routers de aplicaciones de una sola página sin librerías
  • Interceptar navegaciones para guardar cambios pendientes
  • Saber de verdad qué hay en el historial (navigation.entries())

Demo

Una mini app dentro de esta página: los enlaces cambian la URL (?vista=…) sin recargar, y atrás y adelante del navegador también funcionan. «Zona privada» redirige antes de cambiar la URL (precommitHandler).

Compatibilidad

Baseline · nueva · 13 ene 2026
FunciónEscritorioMóvil
ChromeEdgeFirefoxSafariChrome AndroidFirefox AndroidSafari iOS
Navigation (window.navigation)102Chrome: 102 102Edge: 102 147Firefox: 147 26.2Safari: 26.2 102Chrome: 102 147Firefox: 147 26.2Safari: 26.2
intercept({ precommitHandler })141Chrome: 141 141Edge: 141 147Firefox: 147 —Safari: No141Chrome: 141 147Firefox: 147 —Safari: No

Compatibilidad generada en cada publicación desde MDN browser-compat-data 8.1.3 (24 sep 2026) · web-features 3.40.0 · revisión manual: 1 oct 2026

Código mínimo

<!doctype html>
<meta charset="utf-8">
<title>Navigation API · ejemplo mínimo</title>
<!-- Un enrutador de una sola página con la Navigation API. Sírvelo por HTTP (npx serve .), no con file://. -->
<nav>
  <a href="?vista=inicio">Inicio</a> ·
  <a href="?vista=obra">Obra</a> ·
  <a href="?vista=contacto">Contacto</a> ·
  <button id="back">Atrás</button>
</nav>
<main id="view"></main>
<script type="module">
const view = document.querySelector('#view');
const pages = { inicio: 'Bienvenida', obra: 'Trabajos', contacto: 'Escríbeme' };
const render = (url) => {
  const vista = new URL(url).searchParams.get('vista') ?? 'inicio';
  view.textContent = pages[vista] ?? 'No encontrada';
};

if (!('navigation' in window)) {
  view.textContent = 'Sin Navigation API: los enlaces recargan la página.';
} else {
  render(location.href);
  // Un único punto para todas las navegaciones: enlaces, formularios, atrás/adelante, location…
  navigation.addEventListener('navigate', (event) => {
    if (!event.canIntercept || event.hashChange || event.downloadRequest) return;
    const url = new URL(event.destination.url);
    if (url.pathname !== location.pathname) return; // deja pasar lo que no es de esta página
    event.intercept({
      async handler() {
        await new Promise((r) => setTimeout(r, 150)); // aquí iría un fetch
        render(url);
      },
    });
  });
  document.querySelector('#back').onclick = () => navigation.canGoBack && navigation.back();
  navigation.addEventListener('navigatesuccess', () => console.log('Entradas:', navigation.entries().length));
}
</script>

Novedades

  1. Chrome 146 añade addHandler() para el precommitHandler (Firefox 148).
  2. Entra en Interop 2026, con precommitHandler.
  3. Firefox 147 la activa: Baseline.
  4. Safari 26.2 la activa.

Ten en cuenta

  1. Comprueba canIntercept: las navegaciones a otro origen no se pueden interceptar.
  2. Pasar precommitHandler en un evento no cancelable lanza un SecurityError.
  3. Deja pasar las descargas y los cambios de ancla (downloadRequest, hashChange).

Más información

Fuentes