Rutas dinámicas con [param]
El salto de un fichero una URL a un fichero una familia de URLs: los corchetes en el nombre del archivo convierten un segmento en un parámetro, y Astro.params entrega su valor. Por qué el nombre entre corchetes es a la vez patrón y variable, y por qué un patrón obliga a repensar la correspondencia entre estructura y ruta.
El corchete convierte un nombre en una variable
En el enrutado por ficheros, el nombre del archivo es el segmento de la URL. Las rutas dinámicas explotan esa equivalencia con un gesto mínimo: rodear el nombre de corchetes para que deje de leerse como literal y pase a leerse como hueco. src/pages/blog/post.astro casa exactamente con /blog/post; src/pages/blog/[slug].astro casa con /blog/lo-que-sea —con cualquier valor en ese tramo—.
La palabra que escribes dentro de los corchetes no es mágica ni reservada: es un nombre que tú eliges para el parámetro. [slug], [id], [producto] funcionan igual; solo cambia la etiqueta con la que después recuperarás el valor. Elegir un nombre descriptivo es documentar, en el propio fichero, qué representa ese segmento.
src/pages/├─ blog/│ ├─ post.astro -> /blog/post (literal, una URL)│ └─ [slug].astro -> /blog/cualquiera (patron, muchas URL)└─ productos/ └─ [id].astro -> /productos/42, /productos/abc, ...El cambio conceptual es profundo. Un fichero literal responde a la pregunta qué URL sirvo; un fichero con corchetes responde a qué forma tienen las URLs que sirvo. Pasas de enumerar direcciones a describir su gramática. Y esa gramática puede combinar tramos fijos con tramos variables: src/pages/tienda/[categoria]/[id].astro casa con /tienda/ropa/17, con dos parámetros —categoria e id— extraídos de una misma URL.
El orden y la mezcla son libres. Puedes anteponer segmentos literales a los variables, intercalarlos o encadenar varios huecos seguidos —blog/[year]/[slug].astro casa con /blog/2026/mi-post—. Astro respeta los tramos literales como anclas y solo trata como variable lo que envuelves en corchetes. El fichero deja de ser un punto en el mapa de rutas para volverse una plantilla con ranuras, tantas como corchetes contenga.
Astro.params: la ventana al valor concreto
Declarar el patrón es la mitad; leer el valor con el que se ha activado es la otra. Dentro del frontmatter, Astro.params es un objeto cuyas claves son exactamente los nombres de los corchetes de ese fichero. Para [slug].astro, Astro.params.slug te devuelve el tramo que el visitante puso en esa posición de la URL.
---// src/pages/blog/[slug].astroconst { slug } = Astro.params;---<h1>Estas leyendo el post: {slug}</h1>Si alguien visita /blog/hola-mundo, ese mismo fichero se ejecuta con slug igual a hola-mundo. La página no sabe —ni necesita saber— cuántas variantes de sí misma existen: solo recibe el valor de su turno y construye la respuesta a partir de él. Es la inversión exacta del modelo estático: en vez de un fichero por página, un fichero que se reencarna en tantas páginas como valores reciba.
Un detalle que ahorra horas de depuración: el valor de un parámetro es siempre una cadena. La URL es texto, y Astro no adivina tipos por ti. Si tu [id] representa un número, Astro.params.id te llega como "42", no como 42; compararlo con un entero o usarlo como índice sin convertirlo antes es una fuente clásica de fallos silenciosos. La conversión —Number(id), un parseInt— es responsabilidad tuya, y hacerla explícita deja claro dónde cruzas la frontera entre el texto de la URL y el dato tipado de tu lógica.
Algunas consecuencias de que todo parámetro sea texto conviene tenerlas presentes:
- Comparar con un número —
id === 42— siempre falla; compara con la cadena'42'o convierte antes. - Los ceros a la izquierda sobreviven:
007no es7, lo que a veces ayuda y a veces sorprende. - Como índice de un array hay que convertirlo; como clave de un objeto, se usa tal cual.
Cuando un fichero declara varios segmentos dinámicos, Astro.params los reúne todos en un mismo objeto: una clave por cada corchete, poblada en la misma petición. Desestructurarlo es la forma natural de leerlos juntos.
---// src/pages/tienda/[categoria]/[id].astroconst { categoria, id } = Astro.params;---<p>Categoria {categoria} y producto {id}</p>Una sola URL, /tienda/ropa/17, produce dos parámetros a la vez —categoria igual a ropa, id igual a 17— y ambos llegan por ese mismo objeto. El número de claves de Astro.params es exactamente el número de corchetes del fichero: la lectura nunca inventa ni pierde parámetros.
Conviene fijar el vocabulario, porque se confunde a menudo. El segmento dinámico es el hueco en el patrón —[slug], tal como aparece en el nombre del fichero—. El parámetro es la pareja nombre-valor que resulta de casar una URL concreta con ese patrón —slug igual a hola-mundo—. El fichero declara segmentos; cada petición produce parámetros. Uno es la plantilla, el otro es la instancia.
Un patrón describe infinitos casos; el build necesita finitos
Aquí aparece la tensión que gobierna todo este nivel. Un patrón como [slug] describe, en teoría, infinitas URLs: /blog/a, /blog/b, /blog/lo-que-se-te-ocurra. Pero un sitio estático se compila a ficheros HTML antes de que nadie lo visite, y no puede generar infinitos ficheros para infinitos valores imaginables. Alguien tiene que decirle a Astro cuáles de esos infinitos casos existen de verdad.
Esa es la razón de ser de getStaticPaths, la función que veremos en la próxima lección: en modo estático, un fichero con corchetes está obligado a exportarla para enumerar los valores concretos que quiere materializar. Sin ella, Astro no sabe qué páginas hornear y la compilación falla con un error explícito. El patrón describe la gramática; getStaticPaths selecciona las frases de esa gramática que de verdad se pronuncian.
Conviene ver esta obligación como coherencia, no como capricho. Un sitio estático no tiene un proceso vivo que, ante una URL nueva, salga a averiguar si le corresponde una página; todo lo que existe se decidió y se escribió en disco durante el build. Pedirle que sirva un valor que nadie enumeró sería pedirle que consulte a un servidor que no está. Enumerar no es burocracia: es la única forma de que un artefacto sin ejecución en tiempo real sepa qué contiene.
Este modo estático no es el único: en renderizado bajo demanda no hay que enumerar nada, porque el servidor resuelve el parámetro en el momento de cada petición. Pero esa flexibilidad tiene su propio precio y su propia lección al final del nivel. Por ahora, retén la idea vertebral: los corchetes describen qué forma pueden tener las rutas, y decidir cuáles de esas rutas existen es una segunda pregunta, con respuestas distintas según el modo de renderizado.