Saltar al contenido

Pasar datos con props desde getStaticPaths

La segunda clave de cada ruta: mientras params decide la URL, props adjunta los datos ya listos para esa página, que se leen en Astro.props sin repetir la búsqueda. El patrón canónico de una página por entrada de una colección, y por qué params identifica mientras props hidrata.

params identifica, props acompaña

La tentación, al programar una ruta dinámica, es usar el parámetro para volver a buscar el dato dentro de la página: recibo slug, y con él consulto de nuevo la colección para encontrar el post. Funciona, pero es trabajo repetido. getStaticPaths ya tenía delante la colección entera cuando decidió las rutas; obligar a la página a redescubrir lo que aquella ya sabía es dar dos vueltas al mismo dato.

La clave props elimina ese rodeo. En el mismo objeto donde declaras params, adjuntas los datos que la página va a necesitar, y estos llegan intactos a Astro.props.

ASTRO
---// src/pages/blog/[slug].astroexport async function getStaticPaths() {  const posts = await getCollection('blog');  return posts.map((post) => ({    params: { slug: post.id },   // decide la URL    props: { post },             // acompana el dato  }));}const { post } = Astro.props;    // llega ya listo---<h1>{post.data.title}</h1>

La división de trabajo es nítida y merece grabarse. params es lo que se convierte en URL: por fuerza son cadenas, porque una dirección es texto. props es lo que se convierte en contenido de la página: puede ser un objeto rico —la entrada entera, con su data tipado— porque nunca toca la URL. Uno mira hacia fuera, hacia el visitante que teclea la dirección; el otro mira hacia dentro, hacia la plantilla que se va a renderizar.

El patrón: una página por entrada de la colección

Juntando params y props nace el gesto que define el enrutado orientado a datos: recorrer una colección con map y emitir, por cada entrada, un objeto que usa su identificador como params y la entrada completa como props. Un post de la colección, una ruta materializada; añade un post, aparece su página; borra otro, desaparece la suya.

ASTRO
---import { getCollection, render } from 'astro:content';export async function getStaticPaths() {  const posts = await getCollection('blog');  return posts.map((post) => ({    params: { slug: post.id },    props: { post },  }));}const { post } = Astro.props;const { Content } = await render(post);---<article>  <h1>{post.data.title}</h1>  <Content /></article>

Aquí conviven las dos mitades del framework: los datos deciden cuántas páginas hay —una por entrada— y el fichero [slug].astro decide cómo es cada una. El número de páginas ya no lo escribes tú; lo dicta el tamaño de la colección. Es la diferencia entre mantener a mano un fichero por artículo y tener un único fichero que se multiplica solo según el contenido.

Observa un matiz de perspectiva. getStaticPaths ve la colección entera: es una vista global, capaz de razonar sobre el conjunto. Cada página, en cambio, solo ve su rebanada: lo que recibe por props. Esa asimetría no es una limitación, es una herramienta. Como la función tiene delante todos los datos a la vez, puede calcular cosas que una página aislada no podría —y pasárselas ya resueltas—.

Enriquecer con datos derivados: vecinos y cálculo global

El caso que mejor muestra el poder de props es el de los datos que solo existen en relación con el conjunto: el post anterior y el siguiente, la posición en una serie, los artículos relacionados. Una página por sí sola no sabe quiénes son sus vecinos; pero getStaticPaths, que ordena la colección completa, sí lo sabe, y puede adjuntar esa información a cada ruta.

ASTRO
---export async function getStaticPaths() {  const posts = (await getCollection('blog')).sort(    (a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf(),  );  return posts.map((post, i) => ({    params: { slug: post.id },    props: {      post,      anterior: posts[i + 1],   // el conjunto conoce a los vecinos      siguiente: posts[i - 1],    },  }));}---

La página recibe por props no solo su propia entrada, sino su contexto dentro de la colección, calculado una sola vez y ya listo para pintar unos enlaces de navegación. Reproducir esto desde dentro de cada página obligaría a recargar y reordenar la colección entera en cada una —el mismo trabajo global repetido mil veces— para al final quedarte con dos vecinos. props te deja hacer ese cálculo global donde tiene sentido, una vez, y repartir el resultado.