Entendiendo la estructura de un proyecto Astro: src/pages, src/components, src/layouts y public

DUGLAS MORENODUGLAS MORENO 👁 21

Introducción

Astro se ha posicionado como una de las opciones más interesantes para crear sitios web rápidos y optimizados, gracias a su enfoque de "islands architecture" que permite cargar solo el JavaScript necesario. Si recién estás empezando con Astro o querés consolidar tus conocimientos sobre cómo organizar los archivos de un proyecto, este artículo es para vos.

En las próximas secciones vamos a desglosar cada una de las carpetas fundamentales que aparecen al crear un proyecto Astro con el comando npm create astro@latest. Además, incluiremos ejemplos de código con su salida esperada para que veás de forma concreta cómo se relacionan entre sí.

A quién está dirigido: desarrolladores frontend con conocimientos básicos de HTML, CSS y JavaScript (o TypeScript) que quieran iniciar un proyecto con Astro o mejorar su estructura existente.

Qué vas a aprender:

  • La función de cada carpeta principal (src/pages, src/components, src/layouts, public).
  • Cómo crear y usar componentes y layouts.
  • Qué tipo de archivos pertenecen a public y por qué.
  • Buenas prácticas para mantener el proyecto ordenado y escalable.
  • Errores comunes que suelen aparecer al inicio y cómo evitarlos.

¿Por qué la estructura de carpetas importa en Astro?

Astro sigue una convención sobre configuración: el lugar donde colocás un archivo determina sugiere su rol en el proceso de build. Respetar esta convención no solo hace que el proyecto compile sin problemas, sino que también facilita la colaboración y el mantenimiento a largo plazo.

Cuando ejecutás astro build, Astro recorre estas carpetas, transforma los archivos .astro, .md, .mdx, .tsx, etc., y genera un sitio estático optimizado. Conocer qué va donde te permite predecir la salida final y depurar más rápido.


src/pages – Las rutas de tu sitio

La carpeta src/pages es el corazón del enrutamiento. Cada archivo .astro (o .md, .mdx) que pongas aquí se convierte automáticamente en una ruta accesible en el navegador.

Ejemplo básico

Creemos un archivo src/pages/index.astro:

---
// Este es el frontmatter de Astro (opcional)
---
<h1>Bienvenido a mi sitio Astro</h1>
<p>Esta es la página de inicio.</p>

Al iniciar el dev server (astro dev) y visitar http://localhost:4321/, veremos exactamente lo que está dentro del archivo: un encabezado y un párrafo.

Rutas dinámicas

Astro también soporta rutas dinámicas mediante corchetes. Por ejemplo, src/pages/blog/[slug].astro generará rutas como /blog/mi-primer-post.

---
export const getStaticPaths = async () => {
  return [
    { params: { slug: "mi-primer-post" } },
    { params: { slug: "otro-post" } }
  ];
};
---
<h1>Post: {Astro.params.slug}</h1>
<p>Contenido del post aquí.</p>

Salida esperada al visitar /blog/mi-primer-post:

<h1>Post: mi-primer-post</h1>
<p>Contenido del post aquí.</p>

src/components – Componentes reutilizables

Los componentes son piezas de UI que podés reutilizar en múltiples páginas o layouts. En Astro, un componente es simplemente un archivo .astro que no contiene rutas (no está dentro de src/pages).

Creando un componente de tarjeta

src/components/Card.astro:

---
const { title, description, image } = Astro.props;
---
<div class="card" style="border:1px solid #ccc; padding:1rem; max-width:300px;
  <img src={image} alt={title} style="width:100%; height:auto;" />
  <h2>{title}</h2>
  <p>{description}</p>
</div>

Usando el componente en una página

src/pages/about.astro:

---
import Card from '../components/Card.astro';
---
<h1>Sobre nosotros</h1>
<Card
  title="Nuestro equipo"
  description="Somos un grupo apasionado por la web." 
  image=\"https://via.placeholder.com/150\" />

Salida esperada (simplificada):

<h1>Sobre nosotros</h1>
<div class="card" style="border:1px solid #ccc; padding:1rem; max-width:300px;
  <img src="https://via.placeholder.com/150" alt="Nuestro equipo" style="width:100%; height:auto;
  <h2>Nuestro equipo</h2>
  <p>Somos un grupo apasionado por la web.</p>
</div>

src/layouts – Plantillas de página

Un layout es un componente especial que define la estructura común de varias páginas (encabezado, pie de página, etc.). Al usar un layout, evitás repetir código y mantenés la consistencia visual.

Layout básico

src/layouts/BaseLayout.astro:

---
const { title } = Astro.props;
---
<!DOCTYPE html>
<html lang="es">
  <head>
    <meta charset="utf-8" />
    <title>{title}</title>
    <meta name="viewport" content="width=device-width" />
  </head>
  <body>
    <header>
      <h1>Mi Sitio Astro</h1>
      <nav>
        <a href=\"\">Inicio</a> |
        <a href=\"about\">Sobre</a>
      </nav>
    </header>
    <main>
      <slot />
    </main>
    <footer>
      <p>&copy; {new Date().getFullYear()} Mi Sitio Astro</p>
    </footer>
  </body>
</html>

El elemento <slot /> es donde se insertará el contenido de la página que use este layout.

Página que usa el layout

src/pages/contact.astro:

---
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout title="Contacto">
  <h2>Contactanos</h2>
  <form>
    <label>
      Nombre:
      <input type=\"text\" name=\"name\" />
    </label>
    <br />
    <label>
      Email:
      <input type=\"email\" name=\"email\" />
    </label>
    <br />
    <button type=\"submit\">Enviar</button>
  </form>
</BaseLayout>

Salida esperada (fragmento relevante):

<!DOCTYPE html>
<html lang="es">
  <head>
    <meta charset="utf-8" />
    <title>Contacto</title>
    <meta name="viewport" content="width=device-width" />
  </head>
  <body>
    <header>
      <h1>Mi Sitio Astro</h1>
      <nav>
        <a href=\"\">Inicio</a> |
        <a href=\"about\">Sobre</a>
      </nav>
    </header>
    <main>
      <h2>Contactanos</h2>
      <form>
        ...
      </form>
    </main>
    <footer>
      <p>&copy; 2025 Mi Sitio Astro</p>
    </footer>
  </body>
</html>

public – Recursos estáticos

La carpeta public se sirve tal cual, sin procesamiento de Astro. Aquí colocás imágenes, fuentes, archivos robots.txt, manifest.json, o cualquier otro recurso que necesites que esté disponible directamente desde la raíz del sitio.

Ejemplo de uso

Supongamos que tenés una imagen logo.png dentro de public/images/logo.png. Para referenciarla desde cualquier componente o página, usás la ruta absoluta desde la raíz:

<img src=\" /images/logo.png\" alt=\"Logo\" />

Si accedés a http://localhost:4321/images/logo.png, el servidor devolverá la imagen sin modificaciones.

Importante: nada dentro de public pasa por el pipeline de Astro (no se aplica optimización de imágenes, ni se procesa como componente). Por eso es ideal para archivos que ya están optimizados o que no necesitás transformar.


Buenas prácticas para organizar tu proyecto Astro

  1. Mantener las páginas simples: que src/pages contenga solo el markup y las llamadas a datos; la lógica compleja va en componentes o en archivos .ts/ .tsx separados.
  2. Componentes con props tipadas: si usas TypeScript, define una interfaz para las props y exportala junto al componente. Esto evita errores de tipado y mejora el autocompletado.
  3. Layouts anidados: podés tener un layout base (BaseLayout.astro) y luego layouts más específicos que lo extiendan (por ejemplo, BlogLayout.astro que agrega un sidebar). Usá <slot /> en cada nivel.
  4. Agrupar componentes por funcionalidad: crea subcarpetas dentro de src/components como src/components/ui para botones, inputs, etc., y src/components/blog para componentes exclusivos del blog.
  5. Uso de public para assets estáticos: imágenes, favicon, archivos de prueba (robots.txt, sitemap.xml) y cualquier cosa que deba estar disponible sin build.
  6. Nombre de archivos en kebab-case: aunque Astro acepta cualquier convención, la comunidad tiende a usar kebab-case para archivos .astro (ej. post-list.astro).
  7. Separar datos y presentación: si los datos provienen de un CMS o API, obtenélos en un archivo .ts y pasalos como props al componente, en lugar de hacer fetch directamente dentro del .astro.
  8. Aprovechar los collections de contenido: si tenés mucho contenido Markdown/Mdx, usar src/content con la función getCollection mantiene las páginas limpias y permite filtrado y ordenado fácil.

Errores comunes y cómo evitarlos

  • Olvidar exportar el componente: si un archivo .astro no tiene una exportación por defecto (o no se usa como página), Astro lo ignora. Asegurate de que los componentes tengan la estructura correcta y que los importes con la ruta relativa adecuada.
  • Usar rutas relativas incorrectas: al importar un layout o componente desde una página ubicada en subcarpetas, la ruta ../ puede confundirse. Usá la extensión del editor para verificar o usar aliases configurados en tsconfig.json (@components/*).
  • Colocar código de página dentro de public: cualquier cosa que necesite procesamiento (como un .astro o .ts) no funcionará si la ponés en public. Recuerda que public es solo para archivos estáticos.
  • No usar <slot /> en los layouts: si olvidás el slot, el contenido de la página no se mostrará y obtendrás una página vacía.
  • Confundir src/pages con rutas de API: Astro tiene una carpeta especial src/pages/api para endpoints. Si ponés un .ts allí pensando que es un componente, va a fallar. Mantene las API separadas y verificá la documentación.
  • Sobrecargar el frontmatter: el frontmatter de un .astro solo sirve para definir variables y funciones que se ejecutan en build. No pongas lógica de renderizado allí; usá el cuerpo del componente.

Conclusión

Entender la estructura de un proyecto Astro es el primer paso para aprovechar al máximo su potencia y mantener un código limpio y escalable. Hemos visto que:

  • src/pages define las rutas y se convierte en las páginas visibles.
  • src/components alberga piezas de UI reutilizables que se importan donde las necesites.
  • src/layouts brinda plantillas compartidas (encabezado, pie, etc.) mediante el uso de <slot />.
  • public sirve recursos estáticos sin procesamiento alguno.

Aplicando las buenas prácticas y evitando los errores mencionados, podrás crear sitios rápidos, fáciles de mantener y listos para crecer. Ahora te toca a vos: empezá un nuevo proyecto Astro, probá los ejemplos mostrados y experimentá con tus propios componentes y layouts. ¡La isla de código que escribás hoy será la base de la experiencia de tus usuarios mañana!


¿Te quedó alguna duda? Dejála en los comentarios y con gusto te ayudo a resolverla.


Nota: los ejemplos de código fueron testeados con Astro v3.0 y Node.js v20.


Próximos pasos sugeridos:

  • Explorar la ruta src/content para gestionar colecciones de Markdown.
  • Aprender sobre los islands y cuándo usar client:load, client:idle o client:visible.
  • Configurar un entorno de pruebas con Vitest o Playwright para tus componentes Astro.

¡Éxitos con tu próximo sitio en Astro!*

Comentarios (0)

Sé el primero en comentar.

Dejá tu comentario