CodeForge

JavaScript de Cero a Experto / APIs del navegador

History API: el cuaderno de rutas de las SPAs

Teoría20 min20 XP

Navegas por CodeForge y la URL cambia, el botón "atrás" funciona… pero la página NUNCA recarga. Ese truco — el corazón de toda Single Page Application — es la History API: escribir en el historial del navegador sin viajar. Hoy construyes un mini-router con tus manos, y los routers de React y Angular pierden para siempre su aura de magia.

El cuaderno de rutas

Un mini-router en 30 líneas

Navega entre las tres "páginas" mirando la línea de ruta: cambia, el botón activo cambia… y jamás hubo recarga — las variables de tu app siguen vivas. Las piezas del pacto: pushState(estado, "", ruta) anota en el cuaderno (el estado es un objeto tuyo que viaja con la entrada — lo recuperas en event.state); y popstate SOLO se dispara cuando el usuario hojea (atrás/adelante o history.back()) — no cuando tú haces pushState. De ahí la simetría sagrada del router: al navegar TÚ → pushState + pintar; al hojear EL USUARIO → solo pintar.

Esto ES un framework (en miniatura)

Lo que acabas de escribir es, sin exagerar, el núcleo de React Router y del router de Angular: interceptar la navegación, escribir el historial, mapear ruta → vista, y escuchar popstate. Ellos agregan lo industrial (rutas con parámetros como /gastos/:id, carga perezosa, guards) — el mecanismo es ESTE. Y ahora entiendes por qué una SPA se siente instantánea: navegar es pintar un div, no descargar una página.

Dos notas honestas: primera — el 404 fantasma: si el usuario recarga estando en /gastos, el navegador SÍ pide /gastos al servidor… que debe estar configurado para responder la app en cualquier ruta (el famoso "fallback a index.html"; Next y compañía te lo resuelven, y en tu VPS lo hace nginx). Segunda — para estado en la URL tipo filtros (?categoria=comida), el aliado es URLSearchParams + replaceState (que EDITA la entrada actual en vez de anotar una nueva — el historial no se llena de basura por cada tecla).

Tu mini-router funciona al hacer clic, pero cuando el usuario presiona 'atrás', la URL cambia y la vista NO. ¿Qué falta?

Mini-reto

Sube tu router de nivel: 1) agrega la vista /gastos/detalle y navega a ella desde un botón dentro de la vista de gastos (rutas anidadas: funciona igual); 2) guarda en el estado de pushState un contador de navegaciones y muéstralo al volver con atrás (event.state) — para eso existe ese objeto; 3) implementa el filtro con URLSearchParams + replaceState: un input que escriba ?buscar=texto en la URL SIN llenar el historial (comprueba con atrás: un solo paso te saca, no uno por tecla).

Qué sigue

Tour completo: persistencia, observers, hilos, permisos y rutas. El reto del módulo cobra la promesa más vieja del curso: tomar la app interactiva de "Mi Bolsillo" (módulo 8) y hacerla INOLVIDABLE — localStorage para que cada gasto sobreviva a la recarga, con arquitectura limpia de carga y guardado. Tu primera app completa Y persistente.