Astro se ha convertido rápidamente en uno de los generadores de sitios estáticos más populares, y con buena razón. Su arquitectura de islas renderiza el contenido estático como HTML y permite que las funciones interactivas opten por JavaScript en el cliente solo donde sea necesario.
Esta guía recorre las partes de Astro con las que trabajará en su primera semana: configuración del proyecto, componentes, islas, colecciones de contenido, enrutamiento y despliegue. Se asume que se siente cómodo con HTML, algo de TypeScript y la línea de comandos.
Configurando su primer proyecto
Comenzar con Astro es sencillo. Abra su terminal y ejecute el comando de creación:
npm create astro@latest
El asistente de configuración le guiará en la elección de una plantilla, la instalación de dependencias y la configuración de TypeScript. Para la mayoría de los proyectos, la plantilla “Blog” proporciona un excelente punto de partida con las colecciones de contenido ya configuradas.
Cuando termine, inicie el servidor de desarrollo:
cd my-site
npm run dev
El sitio se sirve en http://localhost:4321 con recarga de módulos en caliente. La estructura del proyecto es pequeña y conviene aprenderla pronto:
src/pages/contiene las rutas basadas en archivos.src/pages/about.astrose convierte en/about.src/components/contiene componentes reutilizables. Astro no trata esta carpeta de forma especial; es una convención.src/layouts/contiene las estructuras base de las páginas, de nuevo por convención.public/contiene archivos que se copian a la salida sin modificar, comofavicon.svgorobots.txt.astro.config.mjscontiene integraciones, adaptadores y opciones de compilación.
Entendiendo los componentes de Astro
Los componentes de Astro usan la extensión .astro y combinan una sintaxis similar a HTML con una sección de script frontmatter. A diferencia de los componentes React o Vue, los componentes de Astro se renderizan como HTML estático en el momento de la compilación, a menos que opte explícitamente por la hidratación del lado del cliente.
El frontmatter del componente se ejecuta en el servidor durante la compilación, lo que le da acceso a importaciones de archivos, obtención de datos y funciones utilitarias sin enviar esa lógica al navegador.
---
interface Props {
title: string;
href?: string;
}
const { title, href = "/" } = Astro.props;
---
<article class="card">
<h2><a href={href}>{title}</a></h2>
<slot />
</article>
<style>
.card {
padding: 1.5rem;
border-radius: 0.75rem;
}
</style>
Vale la pena fijarse en algunos detalles de ese ejemplo:
- Las props están tipadas con una interfaz
Propssimple. Los editores yastro checkla reconocen sin configuración adicional. - Los slots funcionan como en los web components. Un
<slot />por defecto recibe los hijos, y los slots con nombre (<slot name="footer" />) reciben los elementos marcados conslot="footer". - Los estilos tienen alcance local por defecto. La regla
.cardanterior solo se aplica a este componente. Use<style is:global>cuando realmente necesite una regla global.
Si ha usado JSX, el principal ajuste es que no hay re-renderizado. La plantilla se ejecuta una vez por solicitud o por compilación, produce HTML y termina.
Islas y directivas de cliente
El HTML estático es el comportamiento por defecto, pero tarde o temprano necesitará algo interactivo: un buscador, un gráfico, un carrito. Astro le permite incorporar componentes de React, Preact, Svelte, Vue o Solid después de añadir la integración correspondiente:
npx astro add react
Un componente de framework renderizado sin directiva sigue generando solo HTML. Para enviar su JavaScript e hidratarlo, añada una directiva client:*:
---
import Counter from "../components/Counter.tsx";
import Chart from "../components/Chart.tsx";
---
<Counter client:load />
<Chart client:visible />
Elija la directiva según la urgencia de la interacción:
client:loadhidrata de inmediato. Úsela para controles en la parte visible inicial que el usuario necesita enseguida.client:idleespera a que el navegador esté inactivo. Adecuada para widgets de menor prioridad.client:visibleespera a que el componente entre en la vista. Ideal para gráficos y contenido incrustado más abajo en la página.client:media="(max-width: 768px)"hidrata solo cuando se cumple una media query, como en un menú exclusivo para móviles.client:only="react"omite por completo el renderizado en el servidor, para componentes que dependen de APIs del navegador.
Cada isla se hidrata de forma independiente, de modo que un widget lento al final de la página no bloquea el resto. Para muchas interacciones ni siquiera necesita un framework: una etiqueta <script> dentro de un componente .astro es empaquetada y deduplicada por Astro, lo que a menudo basta para interruptores, menús y botones de copiar.
Colecciones de contenido
Una de las características destacadas de Astro son las colecciones de contenido. Proporcionan acceso tipado a su contenido Markdown y MDX con validación de esquemas. Defina su estructura de contenido una vez, y Astro asegurará que cada pieza de contenido cumpla con su esquema.
Las colecciones se definen en src/content.config.ts. Desde Astro 5, cada colección usa un loader que indica a Astro de dónde provienen las entradas. El loader integrado glob() lee archivos del disco:
import { defineCollection } from "astro:content";
import { glob } from "astro/loaders";
import { z } from "astro/zod";
const blog = defineCollection({
loader: glob({ pattern: "**/*.{md,mdx}", base: "./src/content/blog" }),
schema: z.object({
title: z.string(),
description: z.string(),
publishDate: z.coerce.date(),
tags: z.array(z.string()).default([]),
draft: z.boolean().default(false),
}),
});
export const collections = { blog };
Si a una publicación le falta el título o tiene una fecha mal formada, la compilación falla con un mensaje que señala el archivo. Eso es exactamente lo que se busca en un equipo: los errores de contenido aparecen en desarrollo, no en producción.
Consultar una colección es una única llamada a función, y los resultados están completamente tipados:
---
import { getCollection } from "astro:content";
const posts = (await getCollection("blog", ({ data }) => !data.draft))
.sort((a, b) => b.data.publishDate.valueOf() - a.data.publishDate.valueOf());
---
<ul>
{posts.map((post) => (
<li><a href={`/blog/${post.id}/`}>{post.data.title}</a></li>
))}
</ul>
Los loaders no se limitan a archivos locales. El loader file() lee un único archivo JSON o YAML, y puede escribir su propio loader para obtener datos de un CMS headless o de una API, manteniendo la misma validación de esquemas y la misma interfaz de consulta.
Enrutamiento y páginas dinámicas
Cada archivo en src/pages/ es una ruta. Para páginas generadas a partir de datos, como una página por cada publicación del blog, use un nombre de archivo entre corchetes y exporte getStaticPaths():
---
// src/pages/blog/[id].astro
import { getCollection, render } from "astro:content";
export async function getStaticPaths() {
const posts = await getCollection("blog");
return posts.map((post) => ({ params: { id: post.id }, props: { post } }));
}
const { post } = Astro.props;
const { Content, headings } = await render(post);
---
<h1>{post.data.title}</h1>
<Content />
render() también devuelve los encabezados de la publicación, algo muy útil para construir una tabla de contenidos sin tener que analizar nada por su cuenta.
Despliegue
Astro soporta múltiples objetivos de despliegue listos para usar. Vercel, Netlify, Cloudflare Pages y los servidores Node tienen cada uno un adaptador oficial que npx astro add instala y configura. Para sitios estáticos, la salida integrada no requiere configuración adicional.
Ejecutar npm run build genera un sitio estático en dist/, que cualquier hosting estático o CDN puede servir. Cuando necesite código que se ejecute en cada solicitud, como el manejo de formularios, la autenticación o las páginas personalizadas, añada un adaptador para su hosting:
npx astro add node
Con un adaptador instalado, puede mantener la mayoría de las páginas prerenderizadas y excluir rutas individuales con export const prerender = false. Antes de desplegar, configure site en astro.config.mjs para que las URL canónicas, los sitemaps y los feeds RSS apunten a su dominio real.
Próximos pasos
Una vez que lo básico le resulte natural, vale la pena explorar algunas funciones aproximadamente en este orden:
- Imágenes. El componente
<Image />deastro:assetsse encarga del redimensionado, los formatos modernos y los atributos de ancho y alto que evitan el desplazamiento del layout. - View transitions. Añadir el componente
<ClientRouter />a su layout proporciona navegación animada en el cliente con muy poco código. - Actions. Las Astro Actions le ofrecen funciones de servidor tipadas con validación de entrada, ideales para formularios de contacto y newsletters.
- Server islands. La directiva
server:deferpermite que una página mayormente estática renderice bajo demanda un fragmento personalizado, como un menú de usuario.
Empiece poco a poco: un layout, una colección, un par de páginas. Astro recompensa ese enfoque porque cada página que añade sigue siendo tan rápida como la primera.