Ahora que ya sabemos la estructura de un fichero .astro
y crear rutas en la carpeta src/pages/
, ya te habrás dado cuenta que en cuanto empieces a crear varias rutas, hay un montón de partes de código que se repiten y que no querrás estar escribiendo una y otra vez, por lo que es necesario reutilizar.
Reutilizando componentes .astro
En Astro (y en la programación en general) es muy importante reutilizar código, para hacerlo todo más simple, más fácil de modificar y evitar repetir la misma información una y otra vez.
Así pues, imagina que tenemos el siguiente fichero src/pages/index.astro
:
---
const sitetitle = "Manz.dev";
const title = "Página principal";
const description = "Una larga y detallada descripción de mi página.";
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
<meta name="description" content={description} />
</head>
<body>
<header>
<h1>{sitetitle}</h1>
</header>
<nav>
<a href="/">Home</a>
<a href="/services/">Services</a>
<a href="/about/">About me</a>
</nav>
<h2>{title}</h2>
<main>
<p>Contenido de la página web en cuestión.</p>
</main>
<footer>
<p>© ManzDev Evil Corp. Todos los derechos reservados. Los izquierdos también.</p>
</footer>
</body>
</html>
Aunque nuestra página es muy simple aún, ya comienza a costar leerla, porque tiene mucho contenido. Además, si pensamos que también tenemos que crear un src/pages/services/index.astro
y un src/pages/about/index.astro
, nos daremos cuenta que la parte de los <nav>
, el <header>
, el <footer>
son siempre iguales. además de tener que repetirlos, si tenemos que cambiar uno, habría que cambiarlo en todas las secciones para actualizarlo.
Separando en componentes
Para evitar esto, vamos a separar ese contenido en componentes. Crearemos una carpeta src/components
y crearemos tres archivos que llamaremos SiteHeader.astro
, SiteNav.astro
y SiteFooter.astro
. A diferencia de la carpeta src/pages
, la carpeta src/components
no crea archivos index.html
en base a los ficheros .astro
, sino que tenemos esa carpeta para añadir contenido que vamos a reutilizar, o simplemente que queremos tener mejor organizado:
Nuestro fichero src/components/SiteHeader.astro
será el encabezado de nuestro sitio web y quedaría como se puede ver a continuación:
---
const sitetitle = "Manz.dev";
---
<header>
<h1>{sitetitle}</h1>
</header>
Por otro lado, nuestro fichero src/components/SiteNav.astro
contendrá la zona de navegación y el código quedaría así:
---
---
<nav>
<a href="/">Home</a>
<a href="/services/">Services</a>
<a href="/about/">About me</a>
</nav>
Por último, nuestro fichero src/components/SiteFooter.astro
contendrá el pie de página y el código que contiene quedaría así:
---
---
<footer>
<p>© ManzDev Evil Corp. Todos los derechos reservados. Los izquierdos también.</p>
</footer>
Si nuestro componente se llama
SiteFooter.astro
, al usarlo deberíamos escribir<SiteFooter />
, respetando mayúsculas/minúsculas. En Astro, los componentes están en PascalCase por convención.
Con esto hemos separado en componentes diferentes. La primera parte ya la tenemos hecha.
Reutilizando componentes
Ahora nos queda reutilizarlos en nuestras páginas de src/pages
(o incluso en otros componentes). Para ello, basta con importarlos y usarlos, lo que requiere un poquito de Javascript (muy poquito). Nuestro fichero src/pages/index.astro
quedaría de la siguiente forma:
---
import SiteHeader from "../components/SiteHeader.astro";
import SiteNav from "../components/SiteNav.astro";
import SiteFooter from "../components/SiteFooter.astro";
const title = "Página principal";
const description = "Una larga y detallada descripción de mi página.";
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
<meta name="description" content={description} />
</head>
<body>
<SiteHeader />
<SiteNav />
<h2>{title}</h2>
<main>
<p>Contenido de la página web en cuestión.</p>
</main>
<SiteFooter />
</body>
</html>
Observa que en la parte superior, hemos importado los componentes creados anteriormente en objetos SiteHeader
, SiteNav
o SiteFooter
. Astro permite utilizar los import de Javascript pero con ficheros .astro
e importándolo como si fueran etiquetas HTML que luego puedes utilizar en la zona inferior de HTML, con el nombre que les hayas puesto.
Observa que, al contrario que con las etiquetas HTML normales, las etiquetas HTML de los componentes de astro se pueden autocerrar
<SiteHeader />
o cerrar de la forma tradicional<SiteHeader></SiteHeader>
.
Siempre que puedas, reutiliza en componentes, para que el código sea más sencillo, especialmente si necesitarás reutilizarlo más adelante. Recuerda también que si comienzas a tener muchos componentes, puedes crear carpetas dentro de src/components
y mantener un orden por categorías, estilos o padres de los componentes.
Nota: Probablemente estés pensando que es una molestia tener que repetir toda la estructura <html>
con su <head>
y demás etiquetas y repetirlas en todas las páginas de src/pages/
. Más adelante veremos una forma de simplificarlas con Layouts, pero primero debemos explicar otras cosas.
Mejorando las rutas de import
Al importar nuestros componentes, es posible que comiences a encontrar molesto tener que buscar la ruta de los ficheros, o te equivoques frecuentemente al escribir la ruta, sobre todo cuando usas muchas carpetas anidadas. Por aquí tienes un truco para simplificar estas rutas:
Observa que en los ejemplos anteriores, hemos utilizado rutas relativas al importar los componentes. Estas rutas se basan en buscar el fichero desde la ruta del fichero actual:
// Si estamos en src/components/Component.astro
import SiteHeader from "../components/SiteHeader.astro";
// Si estamos en src/components/Section/NestedComponent.astro
import NestedComponent from "../../components/SiteHeader.astro";
Como puedes ver, a medida que tengamos rutas más complejas con carpetas y subcarpetas, las rutas se volverán más complicadas de leer y mantener.
Una buena forma de simplificar este tema es crear alias de imports. Básicamente, se trata de crear una ruta especial @
que apunte al contenido de la carpeta src
. De esta forma, los dos import
anteriores se escribirían así:
import SiteHeader from "@/components/SiteHeader.astro";
import NestedComponent from "@/components/SiteHeader.astro";
Ahora no importa donde nos encontremos, siempre empezamos a buscar en src
. Para conseguir este funcionamiento, sólo tenemos que cambiar la configuración de nuestro proyecto en el fichero tsconfig.json
:
{
/* ... */
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
}
}
}
Tienes más información sobre este tema de rutas en Evitar rutas relativas, ya que esto no es algo de Astro, sino de Typescript (con lo que está construido Astro).
En los primeros temas de este curso utilizaré rutas relativas para no complicar en exceso los ejemplos. No obstante, recomiendo encarecidamente utilizar los alias de rutas.