Pasar datos a layouts
Los dos caminos por los que un layout recibe datos: props explícitas desde una página .astro, y el frontmatter de una página Markdown asignada con la clave layout, que Astro inyecta bajo Astro.props.frontmatter junto a otros metadatos.
Un layout es útil porque recibe datos: sin ellos sería un molde rígido que produce siempre la misma página. Astro ofrece dos caminos para alimentarlo. Desde una página .astro pasas props a mano, con total control. Desde una página Markdown, donde no puedes escribir componentes, apuntas a un layout con la clave layout del frontmatter y Astro te inyecta el contenido y los metadatos automáticamente. Dos rutas, un mismo destino: datos que se convierten en documento.
- Repasar el paso explícito de props desde una página
.astrocomo camino manual. - Usar la clave
layoutdel frontmatter de Markdown para asignar un layout a la página. - Leer el frontmatter del Markdown dentro del layout mediante
Astro.props.frontmatter. - Conocer las props que Astro inyecta automáticamente a un layout de Markdown.
Dos caminos para los datos
El mecanismo por el que un layout recibe datos depende del tipo de página que lo use, y conviene tener el mapa claro desde el principio. Una página .astro es código: puede importar el layout, invocarlo como componente y pasarle las props que quiera, calculadas al vuelo. Una página .md o .mdx autónoma es contenido: no escribe JSX ni importa nada, así que Astro le da un atajo declarativo —la clave layout en el frontmatter— y se encarga de conectar los cables por dentro.
flowchart TD A[pagina astro] -->|props a mano| LAY[Layout] B[pagina markdown] -->|clave layout en frontmatter| LAY LAY --> C[Astro.props] B --> D[frontmatter inyectado] D --> LAY style LAY fill:#89b4fa,color:#11111b style C fill:#a6e3a1,color:#11111b
Ambos caminos terminan en lo mismo: el layout recibe datos por Astro.props y los usa para armar el documento. Cambia quién rellena esas props —tú en el caso .astro, Astro en el caso Markdown— y cómo llegan agrupadas.
Props explícitas desde una página .astro
Es el camino que ya conoces, ahora nombrado como lo que es: la vía manual. La página importa el layout y le pasa atributos, que llegan al layout como Astro.props. Tienes control total sobre qué envías, y puedes enviar cualquier valor serializable: cadenas, números, booleanos, arrays y objetos.
---
// src/pages/blog/nota.astro
import BlogLayout from '../../layouts/BlogLayout.astro';
const post = { titulo: 'Una nota', etiquetas: ['astro', 'web'] };
---
<BlogLayout title={post.titulo} tags={post.etiquetas}>
<p>Contenido de la nota.</p>
</BlogLayout>
La virtud de esta vía es la libertad: los datos pueden venir de donde sea —una constante, un cálculo, una llamada a una API en el frontmatter— y decides exactamente cómo se llaman las props y qué contienen. La contrapartida es que eres tú quien los escribe, uno a uno, en cada página.
El atajo layout en Markdown
Una página Markdown que viva directamente en src/pages no puede importar ni invocar componentes, pero sí puede nombrar el layout que la envolverá con la clave layout de su frontmatter, apuntando a la ruta del fichero del layout.
---
layout: ../../layouts/MarkdownPost.astro
title: Mi post escrito en Markdown
date: 2026-07-10
---
# Un encabezado
Todo este cuerpo se convierte en HTML y entra en el slot del layout,
sin que tengas que escribir una sola etiqueta de componente.
Cuando Astro procesa esta página hace dos cosas por ti. Primero, renderiza el cuerpo Markdown a HTML y lo inyecta en el <slot /> del layout indicado, igual que si lo hubieras envuelto a mano. Segundo, pasa todo el frontmatter de la página al layout, para que este pueda usar el título, la fecha o cualquier otro campo que hayas declarado. El resultado es que una página de contenido puro obtiene su marco completo con una sola línea de configuración.
frontmatter: los metadatos del .md como props
Dentro del layout, el frontmatter del Markdown no llega como props sueltas sino agrupado bajo una única prop llamada frontmatter. Ese objeto contiene todos los campos que declaraste en la cabecera del .md.
---
// src/layouts/MarkdownPost.astro
const { frontmatter } = Astro.props;
---
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8" />
<title>{frontmatter.title}</title>
</head>
<body>
<article>
<h1>{frontmatter.title}</h1>
<time>{frontmatter.date}</time>
<slot />
</article>
</body>
</html>
La diferencia con el camino .astro es de forma, no de fondo. Allí nombrabas cada prop por separado; aquí los datos llegan empaquetados en frontmatter porque su contenido es abierto: Astro no sabe qué campos vas a declarar en tu Markdown, así que los reúne todos bajo un mismo espacio de nombres en lugar de esparcirlos. Junto a frontmatter, Astro inyecta a un layout de Markdown otras props útiles que no tuviste que declarar:
frontmatter— el objeto con todos los campos de la cabecera del.md.file— la ruta absoluta del fichero de origen en tu disco.url— la URL pública de la página dentro del sitio.headings— la lista de encabezados del documento, ideal para generar un índice.rawContentycompiledContent— funciones para obtener el Markdown crudo o el HTML compilado.
La clave layout del frontmatter funciona para páginas Markdown que viven sueltas en src/pages. Para contenido estructurado con las content collections —que verás más adelante— el mecanismo es otro: el layout no se asigna en el frontmatter de cada fichero, sino en la ruta dinámica que renderiza la colección, donde recuperas la entrada y pintas su cuerpo con un componente <Content />. No mezcles ambos: el atajo layout es la vía cómoda para Markdown independiente; las colecciones tienen su propio patrón, más potente y tipado.
Los dos caminos de esta lección parecen distintos —uno es código imperativo, el otro configuración declarativa— pero apuntan a la misma verdad sobre qué es un layout: una función pura de sus datos a un documento. Le entra un conjunto de valores por Astro.props y le sale HTML; nada más. Lo revelador es que al layout le da exactamente igual de dónde salieron esos datos. Puedes habértelos calculado a mano en el frontmatter de una página .astro, o puede habértelos extraído Astro del encabezado de un .md y entregado bajo frontmatter: en ambos casos el layout hace lo mismo, porque solo ve props, no procedencias. Esta indiferencia respecto al origen es una propiedad valiosísima y muy general. Es lo que permite que el mismo BlogLayout sirva a un artículo escrito en Markdown por un redactor y a una página generada por código que trae sus datos de una base de datos: el layout no distingue, ni le hace falta. Cuando diseñas una pieza para que dependa solo de sus entradas y no de cómo se produjeron esas entradas, la haces reutilizable en contextos que ni habías imaginado, y la vuelves trivial de probar, porque testearla es solo darle datos y mirar su salida. Los dos caminos de Astro no son dos maneras de usar layouts, sino dos maneras de rellenar el mismo hueco de datos de una función que no pregunta de dónde vienen. Interiorizar que un layout es esa función —datos dentro, documento fuera, origen irrelevante— es lo que te deja combinar contenido escrito a mano, contenido de ficheros y contenido remoto bajo un mismo conjunto de marcos, sin duplicar ni un layout.
- Crea
MarkdownPost.astroque leaAstro.props.frontmattery coloque el título y la fecha en el documento; deja un<slot />para el cuerpo. - Escribe una página
.mdensrc/pagesconlayout,titleydateen el frontmatter y comprueba que su cuerpo aparece dentro del marco con sus metadatos. - Dentro del layout, imprime
headingsyurlpara ver los datos que Astro inyecta sin que los declararas; imagina cómo construirías un índice con ellos. - Reutiliza un mismo layout desde una página
.astrocon props a mano y desde una página.mdcon frontmatter, y verifica que el layout produce el mismo marco sin distinguir el origen.