wandres.dev
EL COMPONENTE .ASTRO · frontmatter y template

Anatomía de un componente .astro

La estructura de un archivo .astro diseccionada pieza a pieza: la valla del frontmatter delimitada por la triple barra, la plantilla HTML que cuelga debajo, y qué responsabilidad asume cada zona dentro del modelo de dos tiempos de Astro 7.

⏱ 12 min

El archivo .astro es la unidad atómica del framework: la pieza con la que armas páginas, layouts y componentes. Su forma es engañosamente simple —una zona de código arriba, HTML debajo—, pero esa división encierra la idea central de Astro. Antes de escribir lógica o plantillas conviene diseccionar la anatomía del archivo y nombrar cada parte con precisión, porque cada zona vive en un tiempo distinto y obedece reglas distintas.

🎯 Al terminar esta lección sabrás
  • Identificar las dos zonas de un .astro: la valla del frontmatter y la plantilla.
  • Entender qué delimita la triple barra --- y por qué esa frontera es semántica, no cosmética.
  • Leer un componente mínimo y nombrar con exactitud cada una de sus partes.
  • Distinguir el .astro como unidad de composición frente a unidad de renderizado.

Un archivo, dos zonas

Un .astro se lee de arriba abajo en dos tramos. Arriba, entre dos líneas de triple guion, vive el frontmatter del componente —también llamado component script—: JavaScript o TypeScript que Astro ejecuta cuando construye la página. Debajo de la segunda valla se extiende la plantilla: un superconjunto de HTML donde insertas los valores calculados arriba. El compilador lee el archivo, separa ambas zonas y las trata de forma radicalmente distinta.

La analogía con el frontmatter de Markdown es deliberada. En un .md, la triple barra encierra metadatos —título, fecha— que no se imprimen en la página. En un .astro, esa misma valla encierra código que sí produce efectos, pero comparte la propiedad esencial: lo que hay entre las barras no aparece literalmente en la salida. Es preparación, no contenido.

---
// zona 1: la valla del frontmatter (component script)
const titulo = "Hola, Astro 7";
const items = ["uno", "dos", "tres"];
---
<!-- zona 2: la plantilla HTML -->
<h1>{titulo}</h1>
<ul>
  {items.map((item) => <li>{item}</li>)}
</ul>

Ese archivo entero es un componente. No hay clase, no hay función render, no hay un export default obligatorio: la estructura misma del archivo —valla arriba, HTML abajo— es la declaración del componente. Astro infiere el resto a partir de la forma.

El compilador de Astro —escrito en Rust, como viste en el primer nivel— no lee este archivo como HTML con código incrustado, sino casi al revés: lo transforma en un módulo cuyo valor exportado es una función de renderizado que devuelve marcado. Esa inversión explica por qué la valla manda sobre la plantilla: primero se ejecuta el código, y solo después se arma el HTML con lo que ese código dejó preparado. El flujo va siempre en un sentido, de la valla hacia la plantilla, nunca de vuelta.

La valla: la triple barra —

La secuencia --- cumple una función sintáctica exacta: abre y cierra la zona de código. La primera aparición marca el inicio del frontmatter; la segunda, su fin y el comienzo de la plantilla. Entre ambas escribes código como lo harías en un módulo de JavaScript, con una diferencia decisiva: se ejecuta una sola vez, del lado del constructor, nunca en el navegador del visitante.

Dentro de la valla mandan las reglas de un módulo ES. import trae dependencias, const y let declaran variables, y el await de nivel superior está permitido porque el frontmatter es asíncrono por naturaleza. Lo que escribes aquí no es un lenguaje de plantillas inventado: es JavaScript o TypeScript real, con toda su potencia y sin dialecto propietario que memorizar.

---
import Boton from '../components/Boton.astro';
const ahora = new Date();
const saludo = ahora.getHours() < 12 ? "Buenos dias" : "Buenas tardes";
---
<p>{saludo}</p>
<Boton />

En esas pocas líneas conviven las tres tareas que más repetirás en una valla: importar una dependencia, calcular un valor derivado y preparar los datos que la plantilla consumirá. Ninguna de las tres viaja al navegador; solo lo hace la cadena de texto que la variable saludo termine valiendo en el instante del renderizado.

ℹ️
La valla vacía y la valla ausente

El frontmatter es opcional. Un .astro que solo contiene HTML es perfectamente válido: sin ninguna barra, todo el archivo es plantilla. También puedes dejar la valla vacía —dos líneas --- seguidas— cuando aún no hay lógica pero quieres marcar el sitio. Lo que no existe es una valla a medias: si abres con ---, debes cerrar con ---, o el compilador no sabrá dónde termina tu código y empieza tu HTML.

La plantilla: HTML debajo de la valla

Bajo la segunda barra empieza la plantilla, y su base es HTML corriente: las mismas etiquetas y los mismos atributos que escribirías en un .html. La diferencia es que Astro la trata como un superconjunto. Acepta expresiones entre llaves —{titulo}— que interpolan los valores calculados en la valla, y admite componer otros componentes, algo que verás en lecciones posteriores.

Un detalle que sorprende a quien viene de React: no necesitas un único elemento raíz. Un .astro puede emitir varios elementos hermanos en su nivel superior sin envolverlos en un fragmento. La plantilla no es una expresión que deba resolver a un solo nodo, sino la descripción de un fragmento de documento que se insertará donde se use el componente.

---
const productos = ["Teclado", "Raton", "Monitor"];
const hayStock = productos.length > 0;
---
<h2>Catalogo</h2>
{hayStock
  ? <ul>{productos.map((p) => <li>{p}</li>)}</ul>
  : <p>Sin existencias</p>}

No te detengas aún en la mecánica de esas expresiones —las llaves, el map, el ternario—: son el tema de una lección posterior. Aquí basta con reconocer la silueta del archivo. Arriba, el catálogo se declara como un dato normal de JavaScript; abajo, la plantilla lo proyecta en marcado. La valla piensa, la plantilla muestra.

📝
El comentario que sí se ve y el que no

Un comentario // o /* */ dentro de la valla es un comentario de JavaScript: se evalúa y desaparece, jamás llega al HTML. Un comentario HTML en la plantilla, en cambio, sí se emite a la salida y queda visible para quien inspeccione el código fuente de la página. Si anotas algo que el visitante no debería leer —una nota de trabajo, un recordatorio—, escríbelo sobre la valla, no en el marcado.

🧩

La valla superior

La primera ---. Abre el frontmatter y marca dónde empieza el código del componente.

🧠

El frontmatter

JavaScript o TypeScript entre las barras. Corre en build o en el servidor, jamás en el cliente.

✂️

La valla inferior

La segunda ---. Cierra el código y abre la plantilla; es la costura entre los dos tiempos.

🖼️

La plantilla

HTML con expresiones {}. Es lo único que se convierte en la salida que ve el navegador.

El modelo mental: composición y renderizado

Un mismo .astro desempeña dos papeles según dónde viva. Colocado en src/pages, es una página: se renderiza a una ruta del sitio. Colocado en src/components, es un componente: se compone dentro de otros. La anatomía no cambia —valla y plantilla— pero el propósito sí, y esa dualidad es la razón de que Astro no distinga sintácticamente entre página y componente.

flowchart TB
FILE[archivo .astro] --> FENCE[valla del frontmatter]
FILE --> TPL[plantilla HTML]
FENCE --> RUN[codigo que corre en build o servidor]
TPL --> EMIT[HTML con expresiones resueltas]
RUN --> OUT[salida HTML sin JS de cliente]
EMIT --> OUT
style FILE fill:#89b4fa,color:#11111b
style OUT fill:#a6e3a1,color:#11111b

Leer la anatomía con esta doble lente evita un error común: creer que las páginas y los componentes son cosas distintas. No lo son. Una página es simplemente un componente que Astro decidió mapear a una URL por vivir en src/pages. Todo lo que aprendas sobre la valla y la plantilla vale para ambos por igual.

---
// una pagina: mismo formato, devuelve el documento completo
import Saludo from '../components/Saludo.astro';
---
<html lang="es">
  <body>
    <Saludo />
  </body>
</html>

La única diferencia práctica es de contrato: una página suele devolver un documento HTML completo —con html, head y body— mientras que un componente devuelve un fragmento pensado para encajar dentro de otro. Pero esa distinción la impone tu diseño, no la sintaxis del archivo: Astro trata a ambos con las mismas reglas de valla y plantilla.

💡
Aprende la anatomía una vez, aplícala en todas partes

Como página, layout y componente comparten anatomía, no hay tres formatos que dominar sino uno solo visto en tres papeles. Cuando entiendas la valla y la plantilla de un componente diminuto, entenderás también la de tu página principal y la de tu layout raíz. Invertir en comprender bien esta estructura mínima rinde en cada archivo .astro que escribas después.

La valla no separa dos sintaxis, separa dos tiempos

Es tentador leer la triple barra como una frontera meramente tipográfica: código arriba, marcado abajo, dos lenguajes que conviven en un archivo. Pero la separación no es de sintaxis, es de tiempo de ejecución. Todo lo que pones sobre la valla ocurre en un instante —el momento en que Astro construye la página o responde a una petición— y luego desaparece: sus variables, sus imports, sus llamadas a la red no dejan rastro en lo que descarga el navegador. Todo lo que pones bajo la valla es lo único que sobrevive a ese instante, congelado ya como HTML. La barra --- es, entonces, la línea entre lo efímero y lo permanente, entre el cálculo y su resultado. Interiorizar esto reordena tu forma de pensar el componente: dejas de preguntarte qué lenguaje va aquí y empiezas a preguntarte cuándo corre esto y qué sobrevive. La misma variable titulo existe en dos mundos —vive arriba como enlace en memoria durante el build, y aparece abajo, ya resuelta, como texto plano en el HTML—. No hay reactividad que las una después, porque no hay un después: cuando el navegador recibe la página, el frontmatter ya se ejecutó y se borró hace rato. Comprender la valla como una costura temporal, y no como un cambio de gramática, es el primer paso para entender por qué Astro envía tan poco JavaScript: casi todo tu componente vivió y murió antes de que existiera el navegador.

⚔️ Disecciona un componente mínimo
  1. Crea src/components/Saludo.astro con una valla que declare const nombre = "Ada" y una plantilla que renderice <p>Hola, {nombre}</p>.
  2. Borra la segunda barra --- y observa el error del compilador: comprueba que una valla sin cerrar rompe el archivo entero.
  3. Restaura las barras y elimina toda la valla dejando solo el HTML; confirma que el componente sigue siendo válido sin frontmatter.
  4. Mueve una copia del archivo a src/pages/saludo.astro, arranca astro dev y verifica que el mismo componente ahora responde en la ruta /saludo.