Cómo guardar una lista de páginas vistas recientemente con Stimulus y localStorage
Crear una lista de “páginas vistas recientemente” puede mejorar significativamente la experiencia del usuario proporcionando navegación fácil e historial de contenido accedido recientemente. Viendo que ya estamos usando Rails, vamos a aprovechar Stimulus. Además, en lugar de almacenar la información en el servidor, usaremos localStorage para persistir los datos de páginas vistas entre sesiones.
¿Por Qué Usar Stimulus y localStorage?
Normalmente para interacciones de UI, prefiero mantener las cosas lo más ligeras posible. Por eso prefiero AlpineJS sobre Stimulus.
Sin embargo, en este caso, Stimulus es una buena elección porque hay un poco más de lógica en el JavaScript.
También usaremos localStorage como mecanismo de almacenamiento del lado del cliente. Es ideal para guardar información no sensible como el historial de páginas porque los datos se almacenan incluso después de que el usuario actualiza o cierra el navegador.
La desventaja de usar localStorage es que si el usuario inicia sesión desde otra computadora, esto no se sincroniza. Es posible sincronizar esta información con lógica adicional en el controlador Stimulus, pero si tu caso de uso es como el mío, probablemente no sea necesario.
El Objetivo
Nuestro objetivo es construir una lista de páginas vistas recientemente que:
- Rastree las páginas visitadas por el usuario.
- Almacene metadatos como el nombre de la página y una breve descripción.
- Muestre hasta las últimas 20 páginas visitadas recientemente.
- Persista estos datos entre sesiones usando
localStorage.
El Controlador Stimulus
A continuación hay un controlador Stimulus que maneja el rastreo y almacenamiento de las páginas visitadas por el usuario:
// app/javascript/controllers/recently_viewed_controller.js
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["currentPath"];
connect() {
if (this.currentPathTargets.length !== 0) {
let name = this.currentPathTarget.dataset.name;
this.saveCurrentPath(name);
}
}
saveCurrentPath(name) {
let path = window.location.pathname;
// Crear un objeto con path, name y description
let pathObject = { path: path, name: name };
// Eliminar objetos existentes con el mismo path
let visitedPaths = this.removePathsContaining(path);
// Agregar el nuevo objeto al principio del array
visitedPaths.unshift(pathObject);
// Mantener solo las últimas 20 entradas
if (visitedPaths.length > 20) {
visitedPaths = visitedPaths.slice(0, 20);
}
// Guardar el array actualizado de vuelta a localStorage
localStorage.setItem("visitedPath", JSON.stringify(visitedPaths));
}
removePathsContaining(substring) {
// Obtener el array existente de localStorage
let visitedPaths = JSON.parse(localStorage.getItem("visitedPath")) || [];
// Filtrar objetos donde el path contiene el substring
visitedPaths = visitedPaths.filter(
(item) => !item.path.includes(substring)
);
return visitedPaths;
}
resetPaths() {
// Limpiar el elemento visitedPath de localStorage
localStorage.removeItem("visitedPath");
}
}
Para activar este controlador y rastrear páginas específicas, necesitarás agregar esto a la etiqueta body:
<body data-controller="smooth-scroll recently-viewed">
<div data-recently-viewed-target="currentPath" data-page-name="<%= @page_name %>">
</div>
/* Tu código */
</body>
Tienes la opción de refactorizar el código anterior o combinarlos. En mi caso de uso, quería agregar el controlador a la etiqueta body para activarlo, y luego opcionalmente guardarlo si agregaba la etiqueta div interna.
Usando la lista de localStorage
Ahora que tienes la lista, puedes acceder a ella con algo como esto:
window.recentlyVisitedPaths = JSON.parse(localStorage.getItem("visitedPath")) || [];
Los valores ahora se devolverán como JSON y puedes renderizarlos usando Stimulus o algo similar.
Ultima actualizacion 31 de agosto de 2024