Deja de parsear URLs con trucos de strings
Antes de que existiera la API URL, la gente se peleaba con las URLs a base de split('?'), expresiones regulares y mucha fe. Funcionaba... hasta que un valor traía un &, un =, un espacio o un carácter no ASCII — y ahí se caía todo. Tanto el navegador como Node ya incluyen un parser de verdad. Úsalo.
Con una sola llamada obtienes todas las partes de la URL ya separadas y decodificadas. El constructor lanza un TypeError cuando recibe una entrada inválida, y normalmente eso es justo lo que quieres: mejor que una URL basura falle de forma ruidosa a que siga corriendo y contamine el resto del flujo.
Cómo leer los parámetros de una URL en JavaScript
Cada objeto URL expone una propiedad .searchParams: un URLSearchParams que sabe leer y escribir el query string:
Hay varios detalles que conviene tener presentes:
- Los valores te llegan ya decodificados.
?name=Ada%20Lovelacedevuelve"Ada Lovelace". - Todo es un string.
"2"no es2. Si necesitas un número, conviértelo conNumber(). - Se permiten claves repetidas.
getdevuelve la primera coincidencia;getAlldevuelve todas. - Las claves inexistentes devuelven
null, noundefined, así que combinan muy bien con?? "default".
Construir un query string en JavaScript
Puedes construir un query string desde cero con URLSearchParams, sin tener que escapar nada a mano ni concatenar con &:
O créalo a partir de un objeto: sirve cualquier iterable de pares [clave, valor], e incluso un objeto plano:
set vs append: set reemplaza cualquier valor existente para esa clave. append agrega otro más. Usa append cuando una clave puede repetirse legítimamente (etiquetas, filtros); usa set para parámetros de un solo valor.
Modificar una URL en JavaScript
Como URL es un objeto vivo, al cambiar searchParams se actualizan .search y .href de forma automática:
Esta es la forma idiomática de añadir un parámetro a una URL existente. Sin tener que comprobar si la URL ya contiene un ?, sin dolores de cabeza sobre si toca anteponer & o ?.
Puedes modificar el resto de partes de la URL exactamente igual:
Recorrer los parámetros de la URL
URLSearchParams es iterable, así que puedes recorrerlo sin complicarte. Con for...of obtienes pares [clave, valor], y también tienes a mano los métodos de siempre: keys(), values() y entries():
Ten en cuenta que las claves repetidas aparecen varias veces: verás tag = web y luego tag = beginner como entradas separadas. Así es fielmente como está la query string real.
Si lo que quieres es un objeto plano para imprimirlo rápido mientras depuras, puedes tirar de Object.fromEntries, aunque ojo: aplasta los duplicados y se queda solo con el último valor:
Sirve para depurar. Pero falla en cuanto una misma clave puede repetirse.
Las URLs relativas necesitan una base
new URL("/search?q=js") por sí solo lanza un error: una ruta relativa no es una URL válida de forma aislada. Hay que pasarle una base como segundo argumento:
Las reglas de resolución son las mismas que usa el navegador con <a href>: una / inicial es absoluta respecto al host, sin barra es relativa a la ruta actual, y .. sube un nivel. Resulta muy práctico cuando armas URLs de una API a partir de una base configurada.
En el navegador, window.location.href te sirve como base lista para parsear la URL de la página actual:
const u = new URL(window.location.href);
const page = u.searchParams.get("page") ?? "1";
Cómo manejar URLs inválidas
El constructor URL lanza un error cuando recibe una entrada mal formada. Eso es útil, pero implica que necesitas un try/catch al parsear una URL en JavaScript que venga del usuario o de un sistema externo:
Los entornos modernos también exponen URL.canParse(input), una comprobación booleana que te ahorra el típico baile de try/catch cuando solo quieres validar la URL:
Un ejemplo práctico
Vamos a juntar todo: leemos los filtros actuales de una URL, los modificamos y generamos una nueva URL para navegar a ella:
Si pasas null, el parámetro se elimina. Cualquier otro valor lo establece o lo sobrescribe. Es un patrón que vas a acabar escribiendo de una forma u otra cada vez que construyas interfaces de filtros, paginación o deep links.
Lo que hay que recordar
new URL(string)parsea una URL y la descompone en partes nombradas. Si le metes basura, lanza un error.url.searchParamses unURLSearchParams: usaget,getAll,set,append,deleteyhas.- La codificación se hace sola. No tires de
encodeURIComponentsalvo que estés armando strings a mano. - Pasa una URL base como segundo argumento para resolver rutas relativas.
URL.canParse(o untry/catch) es tu herramienta de validación para entradas no confiables.
Cada vez que te entren ganas de partir una URL con .split('?') o de sacar un query param con una expresión regular, echa mano de estas APIs. Son más cortas, son correctas y ya vienen incluidas en el runtime.
Preguntas frecuentes
¿Cómo se parsea una URL en JavaScript?
Pásale la cadena al constructor URL: const u = new URL('https://example.com/path?x=1'). El objeto resultante expone protocol, host, pathname, search, hash y el ayudante searchParams. Ojo: lanza una excepción si la URL no es válida, así que envuélvelo en try/catch cuando parsees entradas que no controlas.
¿Cómo obtengo un parámetro de la query string en JavaScript?
Con url.searchParams.get('nombre'). Devuelve el valor ya decodificado, o null si el parámetro no está. Para parámetros que pueden repetirse (?tag=a&tag=b), usa searchParams.getAll('tag') y tendrás todos los valores en un array.
¿Qué diferencia hay entre URL y URLSearchParams?
URL parsea y representa la URL completa: protocolo, host, ruta, query y hash. URLSearchParams se ocupa solo de la parte de la query string y puedes usarlo por separado para construir o leer cadenas tipo a=1&b=2. Además, toda instancia de URL tiene una propiedad .searchParams que es un URLSearchParams enlazado a esa URL.
¿Hace falta codificar los parámetros a mano?
No. URLSearchParams codifica claves y valores automáticamente cuando llamas a set, append o cuando lees el resultado como string. Gestiona bien los espacios, los &, los = y el Unicode. Solo necesitarás encodeURIComponent si te empeñas en construir la cadena a mano, cosa que normalmente no deberías hacer.