Leer el estado de la URL: useParams, useSearchParams, useLocation
La URL es estado reactivo, y el router de Solid ofrece tres lentes para leerlo: useParams devuelve los segmentos dinámicos, useSearchParams lee y escribe la query string, y useLocation expone la dirección entera con pathname, search, hash y estado. Los tres son reactivos, así que leerlos dentro de un efecto o un memo suscribe la UI a los cambios de URL, y los botones de atrás y adelante del navegador funcionan gratis porque la barra de direcciones es la fuente de la verdad.
useParams: los segmentos dinámicos
useParams devuelve un objeto reactivo con los parámetros capturados por los corchetes de la ruta. Leer params.id dentro del JSX, de un memo o de un efecto suscribe ese cálculo al parámetro: si el usuario navega de /usuarios/1 a /usuarios/2 sin salir de la misma plantilla de ruta, el componente no se remonta, pero todo lo que dependa de params.id se re-ejecuta.
import { useParams } from "@solidjs/router";import { createResource } from "solid-js";export default function Usuario() { const params = useParams(); // La fuente reactiva es una funcion que lee params.id: const [usuario] = createResource(() => params.id, cargarUsuario); return <h1>{usuario()?.nombre}</h1>;}Como la ruta se reutiliza entre valores de parámetro, si necesitaras forzar un remontaje —para reiniciar estado interno— envuelves el contenido en un <Show> con keyed sobre params.id. Pero lo habitual es lo contrario: aprovechar que no se remonta para conservar la envoltura y solo recargar los datos.
useSearchParams: leer y escribir la query
La query string —lo que va tras el ?— es estado que tú controlas, no capturado por la ruta. useSearchParams devuelve una pareja al estilo de un signal: un objeto reactivo de lectura y una función de escritura. Leer params.orden reacciona a ?orden=precio; llamar al setter reescribe la URL, fusionando por defecto con los parámetros existentes. Para borrar una clave, le pasas undefined.
import { useSearchParams } from "@solidjs/router";export default function Catalogo() { const [params, setParams] = useSearchParams(); return ( <> <button onClick={() => setParams({ orden: "precio" })}>Por precio</button> <button onClick={() => setParams({ orden: undefined })}>Quitar orden</button> <p>Orden actual: {params.orden ?? "ninguno"}</p> </> );}El setter admite opciones: { replace: true } reescribe la entrada del historial en vez de apilar una nueva, útil para filtros que no quieres que llenen el botón de atrás. Poner el filtro, la pestaña o la paginación en la query tiene una recompensa enorme: el estado se vuelve compartible —copias la URL y quien la abre ve lo mismo— y sobrevive a la recarga.
Un detalle sobre los valores: la query es texto, así que todo lo que leas de useSearchParams es un string o undefined, nunca un número ni un booleano; conviertes en el borde, igual que con cualquier entrada de usuario. Y cuando una misma clave aparece repetida en la URL, el router te la entrega como array, lo que te permite modelar selecciones múltiples sin salir de la barra de direcciones.
import { useSearchParams } from "@solidjs/router";function Filtros() { const [params] = useSearchParams(); const pagina = () => Number(params.pagina) || 1; const etiquetas = () => [params.etiqueta].flat().filter(Boolean); // ?etiqueta=a&etiqueta=b -> ["a", "b"] return <p>Página {pagina()} · {etiquetas().length} etiquetas</p>;}useLocation: la dirección completa
useLocation te da el objeto Location reactivo con la dirección entera descompuesta: pathname, search, hash, un query ya parseado en objeto, el state asociado a la navegación y una key. Es la lente para lo transversal: registrar analítica en cada cambio de página, calcular el enlace activo, decidir el comportamiento de scroll.
import { useLocation } from "@solidjs/router";import { createEffect } from "solid-js";export default function Analitica() { const location = useLocation(); createEffect(() => { // Se re-ejecuta en cada navegacion, porque location es reactivo: registrarVista(location.pathname + location.search); }); return null;}La diferencia práctica con useSearchParams es la dirección del flujo: location.query es de solo lectura, una foto parseada de la query, mientras que useSearchParams es de lectura y escritura. Usa useLocation para observar la URL entera; usa useSearchParams cuando además vas a modificarla.
| Primitivo | Qué lee | ¿Escribe? |
|---|---|---|
useParams |
segmentos dinámicos de la ruta | no |
useSearchParams |
la query string tras el ? |
sí |
useLocation |
pathname, search, hash, state |
no |
Derivar la interfaz de la URL
Como los tres primitivos son reactivos, encajan en el grafo igual que cualquier signal: un createMemo que lee params.orden deriva la vista ordenada y se recalcula solo cuando ese parámetro cambia, venga el cambio de un clic o del botón de atrás. No sincronizas nada a mano; declaras la interfaz como función de la URL y el router se encarga del resto.
import { useSearchParams } from "@solidjs/router";import { createMemo, For } from "solid-js";function Lista(props) { const [params] = useSearchParams(); const ordenados = createMemo(() => ordenar(props.items, params.orden ?? "nombre"), ); return <For each={ordenados()}>{(x) => <Fila dato={x} />}</For>;}El resultado es una interfaz que es, literalmente, una proyección pura de la dirección actual: dos pestañas con la misma URL muestran lo mismo, recargar no pierde nada, y el historial del navegador se vuelve el deshacer y rehacer de tu estado de vista.