37 puntos por GN⁺ 2025-11-03 | 2 comentarios | Compartir por WhatsApp
  • La estructura de la URL funciona no solo como una dirección simple, sino también como un medio para almacenar y restaurar el estado de una aplicación
  • Se presenta el caso de la página de descarga de PrismJS, donde una sola URL reproduce por completo la configuración de tema, lenguaje y plugins
  • Cada componente, como la ruta, los parámetros de consulta y el fragmento, expresa distintos tipos de estado, como navegación jerárquica, filtrado y navegación del cliente
  • Filtros de búsqueda, paginación, modo de vista y rango de fechas son adecuados para incluirse en la URL, mientras que la información sensible o estados temporales de la UI no lo son
  • Una URL bien diseñada mejora la capacidad de compartir, la previsibilidad y la eficiencia del caché, y refuerza la confiabilidad y la experiencia de usuario de las aplicaciones web

El potencial de la URL

  • La URL no es solo la dirección de un recurso, sino que también funciona como una interfaz de usuario (UI) y un contenedor de estado
    • Conserva automáticamente el estado al compartir, guardar en marcadores, usar el historial del navegador y crear deep links
    • Ha funcionado como el mecanismo básico de gestión de estado de la web desde 1991
  • Cada componente de la URL representa un tipo distinto de estado
    • Ruta (Path): exploración jerárquica de recursos (/users/123/posts)
    • Consulta (Query): filtros, opciones y configuraciones (?theme=dark&lang=en)
    • Fragmento (Fragment): ubicación dentro del documento o enrutamiento SPA (#features, #/dashboard)
  • La función de Text Fragments permite enlazar directamente a un texto específico dentro de una página

Patrones de parámetros de consulta

  • Método de usar un delimitador (delimiter) para poner varios valores en una sola clave (?tags=frontend,react,hooks)
  • Serialización de datos anidados en JSON o Base64 (?config=eyJyaWNrIjoicm9sbCJ9==)
  • Los flags booleanos se expresan con la sola presencia de la clave (?mobile)
  • La notación de arreglos (bracket notation) expresa múltiples valores en la forma tags[]=frontend&tags[]=react
    • Se reconoce automáticamente en qs de Node o en middlewares de Express, pero no está estandarizada
  • La clave está en mantener la consistencia

Casos de representación de estado mediante la URL

  • PrismJS: guarda toda la configuración de tema, lenguaje y plugins en el hash de la URL
  • GitHub: resalta un rango específico de líneas de código con #L108-L136
  • Google Maps: incluye coordenadas, nivel de zoom y tipo de mapa en la URL
  • Figma: comparte mediante URL el contexto de trabajo, como la posición del lienzo, el zoom y los elementos seleccionados
  • Sitios de comercio electrónico: incluyen filtros, ordenamiento y rango de precios en la URL para restaurar el estado de búsqueda

Patrones de ingeniería frontend

  • Estado adecuado para incluir en la URL
    • término de búsqueda, filtros, página y orden, modo de vista, rango de fechas, pestaña activa, configuración de UI, flags de funciones
  • Estado inadecuado para la URL
    • información sensible como contraseñas o tokens, estados temporales de UI, entradas no guardadas, datos de gran tamaño, estados de alta frecuencia
  • Criterio de decisión: ¿otro usuario debería ver el mismo estado al hacer clic en la misma URL?

Implementación en JavaScript

  • La API URLSearchParams permite leer y escribir parámetros de consulta
  • pushState agrega una nueva entrada al historial y replaceState actualiza la actual
  • El evento popstate restaura la UI al usar el botón Atrás del navegador

Implementación en React

  • El hook useSearchParams de React Router permite gestionar de forma concisa el estado en la URL
    • Al leer o actualizar parámetros, sincroniza automáticamente la URL y la UI

Buenas prácticas para gestionar estado con la URL

  • No incluir valores predeterminados en la URL (mantener solo ?theme=dark; los valores por defecto se resuelven en el código)
  • Evitar actualizaciones excesivas de la URL durante la escritura mediante debouncing (usando lodash.debounce)
  • pushState vs replaceState
    • pushState: para estados reversibles, como cambios de filtro o navegación entre páginas
    • replaceState: para ajustes finos, como la entrada de búsqueda

Ver la URL como un contrato (Contract)

  • Una URL bien diseñada actúa como un contrato explícito entre la aplicación y el usuario
    • Aclara los límites entre estados públicos/privados, cliente/servidor y compartidos/de sesión
  • Una URL legible comunica la intención y puede ser entendida tanto por personas como por máquinas
    • Una forma como example.com/products/laptop?color=silver&sort=price transmite mejor el significado
  • Mejora de la eficiencia del caché
    • La misma URL se considera el mismo recurso, lo que aumenta la tasa de aciertos en caché
    • Los parámetros de consulta permiten controlar variantes de caché
  • Versionado y experimentos
    • ?v=2, ?beta=true, ?experiment=new-ui permiten distinguir versiones de API y pruebas A/B

Antipatrones que se deben evitar

  • Mantener el estado solo en memoria en una SPA, perdiéndolo al recargar la página
  • Incluir información sensible en la URL (?password=secret123)
  • Nombres de parámetros poco claros (?foo=true&bar=2 en lugar de ?mobile=true&page=2)
  • Codificar JSON complejo en Base64, generando URLs excesivamente largas
  • Superar el límite de longitud de la URL (existen restricciones de navegadores, servidores y CDN)
  • Anular el botón Atrás (puede ocurrir por abuso de replaceState)

Conclusión

  • Una buena URL hace más que apuntar a contenido: expresa una conversación entre el usuario y la aplicación
  • La URL es el medio de gestión de estado más antiguo y elegante para contener intención, contexto y posibilidad de compartir
  • Aunque existen herramientas complejas de gestión de estado como Redux, MobX, Zustand y Recoil,
    no olvidar esta capacidad básica de la URL es una de las verdaderas fortalezas de la web
  • Una app que pierde el estado al recargar está pasando por alto una característica esencial de la web

2 comentarios

 
GN⁺ 2025-11-03
Opiniones en Hacker News
  • En las revisiones de código intento guardar la mayor cantidad posible de estado (state) en la URL
    Que después de recargar te mande a un lugar completamente distinto, o que una URL compartida muestre una pantalla equivocada, es ofensivo desde la perspectiva del usuario
    Este enfoque ralentiza el desarrollo, pero dentro del equipo eleva la conciencia sobre UX y deja más claro cuánto estado estamos metiendo en la vista
    También existe la preocupación de que la URL se convierta en una especie de API pública y eso imponga restricciones, pero creo que no es un gran problema porque la mayoría de las URL solo se usan a corto plazo
    Si hace falta, se puede resolver con código que al cargar migra la URL anterior a una nueva

    • Me gusta este enfoque, pero a veces el autocompletado del historial del navegador recupera estados no deseados
      Creo que usar query parameters en vez de la ruta (path) funciona un poco mejor
    • La web app de trabajo que uso creó su propio botón de “atrás” y por eso el botón Atrás del navegador quedó completamente roto
      Desde la perspectiva del usuario, la palabra “atrás” está asociada al botón del navegador, así que eso genera confusión
      Que al recargar se reinicie el estado molesta menos, porque existe la idea de que “recargar = empezar de nuevo”
    • Si la página usa renderizado del lado del servidor, al recargar se restaura automáticamente la posición de scroll
      Cuando todo se maneja con JS, estas funciones básicas se rompen de forma sutil
    • Creo que el diseño de URL es parte del diseño UX
      Pero incluso después de trabajar con más de 30 diseñadores UX, nunca he recibido una guía sobre URL
    • A medida que la web evolucionó, el significado de recargar pasó a depender del contexto
      Sobre todo en móvil, donde es difícil devolver una página a su estado inicial, recargar termina siendo la solución más rápida
      En interfaces con scroll infinito o filtros complejos, cuanto más estado haya en la URL, más tedioso se vuelve reiniciar todo
      Si el usuario ya está molesto con la UX y además tiene que ordenar la URL, eso le genera un estrés doble
  • Siento que incluso las personas con alta alfabetización digital tienen poca comprensión de las URL y el DNS
    Deberían ser capaces de reducir el riesgo de phishing, entender el significado de parámetros de URL (?t=_, utm_) y eliminar información personal antes de compartirlas
    También deberían saber que el candado de HTTPS no significa ‘confianza’

    • Pero es difícil educar sobre eso cuando los navegadores por defecto ocultan o abrevian la URL, y las empresas promocionan solo códigos QR o palabras de búsqueda
  • Si usas la URL como contenedor de estado, la estructura interna queda expuesta y hace falta versionado
    También puede haber problemas en la compatibilidad entre navegadores o en los flujos de autenticación
    Aun así, intento exponer en la URL la mayor cantidad de estado posible, como si fueran argumentos de línea de comandos
    Pero este es un trade-off intencional, no el resultado de ignorancia o falta de experiencia

  • Recomiendo Rison, una librería antigua pero todavía útil
    Permite guardar JSON de forma limpia en la URL y también se usa en Kibana de Elastic
    Ejemplo: http://example.com/service?query=q:'*',start:10,count:10

    • ¡Esto era justo lo que estaba buscando! Antes me improvisaba algo casero, pero esto se ve mucho más estándar y ordenado
  • A medida que un sistema evoluciona, también cambia la estructura del estado, así que meterlo en la URL limita esa evolución
    Eso se debe a que la URL es básicamente una cadena permanente
    En cambio, creo que lo apropiado es ver la URL como una especie de protocolo y codificar/decodificar el estado
    Si la página es simple, incluso es posible meter todo el estado en la URL

    • En contenido de larga vida útil (por ejemplo, un post de blog), conservar el estado en la URL es útil
      Pero en algo como un feed depende de las expectativas del usuario, por ejemplo: “¿al recargar debería volver al estado más reciente?”
    • Introducir versionado puede ayudar a aliviar este problema
  • El límite de longitud de una URL varía según la configuración del navegador, el servidor, el CDN o el motor de búsqueda, pero normalmente está por debajo de 2000 caracteres
    Eso hace pensar cuánta información de estado se puede meter ahí, o si hace falta otro enfoque

    • Excluyendo el dominio, cada carácter puede usar 66 posibilidades (mayúsculas, minúsculas, números y los caracteres especiales - . _ ~), así que la densidad de información es bastante alta
  • draw.io puede guardar el estado completo en la URL para compartirlo
    Los datos del diagrama se codifican en Base64, así que con un solo enlace se puede restaurar todo por completo
    Aunque no estoy seguro de que eso encaje con la definición de ‘state container’

  • En mis apps self-hosted uso hash routing (#/dashboard)
    No hace falta reescritura de URL del lado del servidor (.htaccess, etc.), así que aunque no es perfecto, reduce las restricciones del entorno de despliegue

  • La versión moderna de Microsoft Teams maneja todas las pantallas con una sola URL, así que no se pueden marcar
    Es muy incómodo no poder abrir directamente un equipo o canal específico

  • HATEOAS no llama mucho la atención porque su nombre no ayuda, pero al final es un concepto básico de la web

    • Desde la perspectiva del usuario, seguir enlaces y enviar formularios ya es HATEOAS
      Pero en entornos donde controlas tanto el servidor como el cliente, solo añade complejidad extra
      Sobre todo si el cliente igual necesita conocer la estructura de los endpoints, porque entonces la URL solo se vuelve opaca
    • En realidad este tema no está directamente relacionado con HATEOAS. Ambos usan URL, pero HATEOAS no trata de almacenamiento de estado, sino de estructura de navegación
    • Es una broma, pero al final a HATEOAS le quedaría mejor el nombre de “cerealización (cerealization)
 
ndrgrd 2025-11-03

Uso mucho la función de suspensión de pestañas, pero las webapps que fijan todo en una sola URL y se mueven como un bloque pierden la información cuando entran en suspensión.

Pero además, esas páginas web siempre son pesadas, así que tampoco puedes no ponerlas en suspensión.