En esta guía práctica de Astro, te guiaré a través del proceso de configuración y te mostraré cómo estructurar tus archivos. Aprenderás a añadir páginas, componentes interactivos e incluso posts en markdown.
También te mostraré cómo obtener datos de un servidor, crear diseños y añadir interactividad utilizando vanilla JavaScript y otros frameworks. Y prepárate para un poco de diversión práctica porque vamos a crear una pequeña instancia de Bejamas sitio web juntos. Vamos a construir un sitio web de varias páginas, incluyendo un blog.
Al final de este post, tendrás una buena comprensión de cómo funciona Astro y cómo se puede utilizar para crear sitios web eficientes más rápido. Vamos allá.
¿Qué es Astro?
Como desarrolladores, sabemos que crear una gran experiencia de usuario es clave a la hora de construir un sitio web. ¿Y qué es lo que más les gusta a los usuarios? Sitios web rápidos que no les hagan perder el tiempo. Con Astro, podemos conseguirlo enviando menos código al navegador.
Todos tenemos nuestros frameworks de interfaz de usuario favoritos que nos hacen la vida más fácil, pero pueden tener el coste de un sitio web pesado. Pero con Astro, podemos tener lo mejor de ambos mundos.
Nos permite construir nuestro sitio web con nuestro framework favorito e incluso múltiples frameworks al mismo tiempo, pero los convierte en HTML estático en el momento de la construcción. Por lo tanto, podemos crear un sitio web rápido para nuestros usuarios sin sacrificar la experiencia del desarrollador moderno.
Pero Astro no se queda ahí. También nos permite optar por JavaScript dinámico, del lado del cliente, según sea necesario, lo que significa que podemos tener componentes interactivos en nuestro sitio web, pero sólo cuando sea necesario. En otras palabras, Astro permite empezar de forma sencilla e ir añadiendo complejidad cuando sea necesario.
En resumen, Astro es un potente framework que soporta tanto la generación de sitios estáticos (SSG) como el renderizado del lado del servidor (SSR) para ayudarnos a construir sitios web rápidos y basados en contenidos, sin perder de vista la experiencia del desarrollador.
Es ligero, eficiente y flexible, lo que lo convierte en una opción adecuada para crear sitios web ricos en contenido, como blogs, portfolios, documentación y algunos sitios de comercio electrónico.
Si quieres crear una aplicación web compleja con mucha interactividad, Astro puede que no sea la opción adecuada para ti. En su lugar, puedes considerar otras herramientas como Next.js.
Genial, ahora que tenemos una buena comprensión de lo que es Astro y lo que puede hacer, ¡vamos a sumergirnos y ver lo que podemos construir juntos!
Primeros pasos con Astro
Primero, instalemos Astro y creemos la semilla del proyecto. Asegúrate de que tienes la versión 16.12.0 o superior de Node.js instalada en tu máquina.
npm create astro@latest
Si utiliza Yarn:
yarn create astro@latest
El CLI te preguntará por el nombre del proyecto y si quieres usar Typescript. Además, te dará algunas opciones sobre cómo te gustaría configurar tu proyecto. Para el tutorial, estoy eligiendo la opción "un proyecto vacío".
Aquí está mi mini-chat con Astro CLI:
Una vez que abras tu proyecto en tu editor puedes instalar la extensión de Astro. Dado que Astro tiene su propia extensión de archivo y sintaxis, es posible que desees instalar su extensión para su editor.
Aquí tienes el enlace a la extensión de Astro para VSCode, que hace mucho más que resaltar la sintaxis por ti.
Ahora puedes ejecutar tu proyecto con el siguiente comando. No necesitas instalar ninguna dependencia.
npm run dev
Abre tu navegador y ve a http://localhost:3000
y disfruta de la primera vista de tu proyecto casi vacío.
Estructura del proyecto Astor
La estructura de archivos de Astro es bastante sencilla.
src
: Tu código fuente (componentes, páginas, estilos, etc.)public
: Tus activos (fuentes, iconos, etc.)
En el directorio src/pages
, Astro crea un archivo index.astro
que puedes considerar como tu index.html
.
Es importante tener en cuenta que, el src/content/
es un directorio reservado en Astro.
Astro v2.0
introdujo la API de Colecciones para organizar tus archivos Markdown y MDX en colecciones de contenido. Esta API reserva src/content/
como una carpeta especial.
Páginas Astro
Muy bien, hablemos de las páginas en Astro. Las páginas Astro manejan el enrutamiento, la carga de datos y el diseño general de cada página de tu sitio web. Son archivos con diferentes extensiones que viven en el subdirectorio src/pages/.
En Astro, tenemos diferentes tipos de páginas, incluyendo .astro
, .md
, .mdx
, .html
e incluso .js/.ts
. Cada uno de estos tipos de archivo tiene un propósito diferente y se puede utilizar de diferentes maneras para crear tus páginas.
Astro utiliza una estrategia de enrutamiento llamada enrutamiento basado en archivos, lo que significa que cada archivo en su directorio src/pages/
se convierte en un punto final en su sitio basado en su ruta de archivo. Esto permite flexibilidad y fácil organización de tus páginas.
En este tutorial, crearemos principalmente páginas con archivos .astro
y .md.
Ten en cuenta que si usas páginas .html algunas características clave de Astro no son soportadas en componentes HTML.
Ahora vamos a crear la segunda página para ver cómo funciona. Todo lo que necesitas hacer es crear un archivo junto a index.astro
en el directorio src/pages
.
Lo llamaré about.astro
y escribiré un código muy simple dentro de él:
<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" />
<title>About</title>
</head>
<body>
<h1>About</h1>
<p>Jamstack development agency.</p>
</body>
</html>
Ahora puedes visitar localhost:3000/about
para ver esta página en tu navegador. Como puedes ver la ruta /about
funciona tan pronto como añades el archivo a la carpeta pages.
Puedes actualizar el contenido o incluso añadir tu propio estilo interno y Astro se encargará de la previsualización en vivo por ti. Así que no hay necesidad de instalar ningún paquete NPM live-reload
o ese tipo de cosas.
Para poder navegar fácilmente entre páginas voy a añadir navegación a mis archivos index.astro
y about.astro
:
<body>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
<h1>About</h1>
<p>Jamstack development agency.</p>
</body>
Pero no querrás tener que actualizar todas tus páginas cada vez que añadas un enlace a tu navegación, ¿verdad?
Aquí es donde los componentes entran en juego y te ayudan a no repetirte.
Componentes Astro
Los componentes Astro son los bloques básicos de cualquier proyecto Astro. Tienen dos partes principales:
- Componente Script
- Plantilla de componentes
Este es el aspecto de un componente Astro:
---
// Component Script (JavaScript)
---
<!-- Component Template (HTML + JS Expressions) -->
Vamos a añadir nuestro primer componente al proyecto.
Voy a crear un directorio src/components
y añadir un archivo header.astro
dentro de él. Luego, voy a mover mi marcado de navegación dentro del componente Header
. Por ahora, la parte script de nuestro componente puede permanecer vacía.
---
---
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
El siguiente paso es añadir el componente a nuestras páginas. Para ello, necesitamos importar el componente. Así que abre tu archivo about.astro
y añade el siguiente import al principio de tu archivo:
---
import Header from ‘../components/Header.astro’;
---
<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" />
<title>About</title>
</head>
<body>
<h1>About</h1>
<p>Jamstack development agency.</p>
</body>
</html>
Ahora que el componente de cabecera está importado, podemos utilizarlo así:
<body>
<Header />
<h1>About</h1>
</body>
Haga lo mismo para la página de inicio que es su archivo index.astro
en su directorio pages.
Ahora, si compruebas estas páginas en tu navegador, deberías ver que tu cabecera está bien.
Por último, voy a añadir nuestro logotipo y algunas marcas semánticas a nuestra cabecera junto con un contenedor para que pueda añadir algunos estilos más tarde:
<header>
<div class="container">
<a class="logo" href="/">
<svg><!-- SVG Logo goes here --></svg></a>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
</div>
</header>
Esto es lo impresionante de Astro. Hasta ahora, hemos hecho páginas y les hemos añadido componentes sin escribir casi nada más que HTML.
Añadiendo Script a Code Fences
Los Code Fences son la parte de script de tu componente Astro. Puedes usar una valla para escribir cualquier JavaScript que necesites para renderizar tu plantilla. ¡Incluso puedes escribir TypeScript! 😎
---
// The code fence area
---
Por ejemplo, en la sección anterior, añadí una línea de importación a mi valla de código para añadir el componente Encabezado a mi página. Veremos qué más podemos hacer en una valla de código a medida que avancemos en este artículo.
La razón por la que se llama code fence es que cualquier código JavaScript que escribas en él está "cercado" y no puede escapar al navegador y llegar a las manos de tu usuario. Todo lo que escribas aquí sólo está ahí para ayudar a tu plantilla de componentes.
Volvamos a nuestras páginas y agreguemos una variable a las vallas de código de las páginas para almacenar el título de la página:
---
import Header from ‘../components/Header.astro’;
const pageTitle = ‘Bejamas’;
---
<html lang="en">
<head>
<title>{pageTitle}</title>
</head>
<body>
<Header />
<h1>{pageTitle}</h1>
</body>
</html>
Como puedes ver en el fragmento anterior, puedes definir variables JavaScript locales dentro de la valla de código y luego inyectar la variable en la plantilla HTML utilizando expresiones similares a JSX.
Ahora haz lo mismo en tus otras páginas como about.astro
, etc.
Al mirar tus diferentes páginas puede que empieces a notar algo molesto de nuevo. Sí, te repites cuando escribes lo mismo en diferentes páginas. Todas las líneas de código de tus páginas son exactamente iguales excepto el título.
Supongo que es un buen momento para hablar de los diseños en Astro.
Plantillas con Astro Layouts
Los diseños Astro son sólo componentes Astro con diferentes nombres que se utilizan para crear una estructura de interfaz de usuario o diseño, como una plantilla de página. Por lo tanto, cualquier cosa que puedas hacer dentro de un componente es posible realizarla dentro de un diseño.
Puedes colocar tus archivos de diseño en cualquier lugar de tu proyecto, pero es una buena práctica añadirlos dentro del directorio src/layouts
En nuestro proyecto, había algunas marcas compartidas a través de las páginas que podrían ser utilizadas como plantilla para evitar repetirlas en diferentes archivos. Para ello, vamos a crear un archivo BaseLayout.astro
en el directorio src/layouts.
Copiamos y pegamos el contenido de mi index.astro
dentro de este archivo:
---
import Header from '../components/Header.astro';
const pageTitle = 'Bejamas';
---
<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" />
<tittle>{pageTitle}</tittle>
</head>
<body>
<Header />
<h1>{pageTitle}</h1>
</body>
</html>
Acabas de hacer tu primer diseño Astro y ahora necesitas utilizarlo en tus páginas Astro. Veamos cómo puedes hacerlo.
Como en el caso de los componentes, el primer paso es importar el layout
a la valla de código, y luego usarlo colocando su etiqueta en la parte de la plantilla. Así que este es el aspecto que tendrá astro.index
:
---
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout></BaseLayout>
Si intenta hacer lo mismo para su página Acerca de, te darás cuenta de que hay un contenido diferente dentro de about.astro.
Necesitas mantenerlo o de alguna manera pasarlo a tu archivo BaseLayout
. Aquí es donde resulta útil.
El elemento
El elemento es un marcador de posición para contenido HTML externo. Especifica dónde deben inyectarse los elementos hijos de otros archivos en la plantilla de tu componente.
Puedes agregar este elemento a tu archivo BaseLayout.astro
como el siguiente código:
---
import Header from '../components/Header.astro';
const pageTitle = 'Bejamas';
---
<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" />
<title>{pageTitle}</title>
</head>
<body>
<Header />
<h1>{pageTitle}</h1>
<slot /> <!-- your content is injected here -->
</body>
</html>
Ahora, el contenido de la página Acerca de puede ir entre la etiqueta BaseLayout
así:
---
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout>
<p>Jamstack development agency.</p>
</BaseLayout>
Y si compruebas tu navegador, verás como ambas páginas funcionan con la misma plantilla pero diferente contenido.
Sólo hay una parte en la que nos hemos equivocado, el título de las páginas. En mi ejemplo, ambos títulos son "Pijama".
¡Aquí es donde los componentes de apoyo vienen al rescate!
Componentes Astro
Aparte de los Slots
, otra característica de los componentes Astro que puede ser muy útil en los layouts
son los Props
. Cualquier componente Astro puede definir y recibir apoyos. Definiendo props
aparte de las partes de la plantilla, los haces disponibles para las partes de scripting de tus componentes a través del global Astro.props.
En nuestro ejemplo, podemos definir un prop pageTitle
y pasarlo a nuestro componente BaseLayout
para poder tener diferentes títulos de página en diferentes páginas.
Así es como puedes definir una prop en el componente BaseLayout
:
---
import Header from '../components/Header.astro';
const { pageTitle } = Astro.props;
---
<html lang="en">
<head>
<title>{pageTitle}</title>
</head>
<body>
<Header />
<h1>{pageTitle}</h1>
<slot /> <!-- your content is injected here -->
</body>
</html>
Observa cómo hemos utilizado la sintaxis de desestructuración para extraer los props del objeto global Astro.props
. Si tuvieras más props podrías usar una coma como la línea de abajo:
const { pageTitle, pageDescription } = Astro.props;
Ahora veamos como puedes pasar una prop
a tu componente o layout.
La página index.astro
puede simplemente pasar la prop
pageTitle
como un atributo como este:
---
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout pageTitle="Bejamas"></BaseLayout>
También puedes definir una variable en tu script frontmatter
para estar más organizado. Hagámoslo para nuestra página Acerca de:
---
import BaseLayout from '../layouts/BaseLayout.astro';
const pageTitle = 'About';
---
<BaseLayout pageTitle={pageTitle}>
<p>Jamstack development agency.</p>
</BaseLayout>
Hasta ahora, no te he mostrado ninguno de los resultados. La razón ha sido la falta de estilo, así que vamos a añadir algo de CSS.
Estilo en Astro
Los proyectos Astro pueden ser estilizados de varias maneras, que no podemos cubrir aquí. Debes saber, sin embargo, que Astro soporta cualquier método que se te ocurra. Puedes escribir CSS plano, Sass y Módulos CSS o incluso importar tu librería CSS favorita como Tailwind.
Puedes añadir una etiqueta <Style>
directamente a tu componente o plantilla de página.
---
---
<style>
.container { /* */ }
nav {
display: flex;
gap: 1rem;
}
nav a { /* */ }
</style>
<header>
<div class="container">
<a class="logo" href="/">
<svg><!-- SVG Logo goes here --></svg></a>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
</div>
</header>
Por defecto, las reglas CSS <Style>
de Astro están encapsuladas dentro del componente. Esto significa que los estilos que se escriben en este componente no se filtran y no afectarán al resto del sitio.
Aparte del componente Cabecera, añadiré el resto de los estilos a un archivo CSS externo y lo importaremos como un estilo global en el proyecto.
:root {
--color-primary: #da3654;
--color-text: #000;
--color-text-2: #3c4856c2;
}
@font-face {
font-family: "Recoleta";
src: url
}
Body {
margin: 0;
font: 100%/1.55 "poppins", sans-serif;
scroll-behavior: smooth;
}
:is(h1,h2,h3,h4) {
font-family: "Recoleta" , "poppins";
}
Así es como puede importar su archivo CSS externo en su archivo BaseLayout.astro
:
---
import Header from '../components/Header.astro';
import '../styles/global.css';
const { pageTitle } = Astro.props;
---
<html lang="en">
<head>
<title>{pageTitle}</title>
</head>
<body>
<Header />
<h1>{pageTitle}</h1>
<slot />
</body>
</html>
Antes de pasar a la siguiente sección, voy a compartir una demostración de trabajo aquí. Hemos añadido algo de contenido estático a las páginas Inicio y Acerca de y se escribieron algunos estilos.
Esto es lo que he añadido a mi página de inicio:
---
import BaseLayout from '../layouts/BaseLayout.astro';
const pageTitle = 'Bejamas';
---
<BaseLayout pageTitle={pageTitle}>
<section class="section">
<div class="container">
<div class="banner">
<div class="">
<h3 class="pretitle">Jamstack Developers for hire</h3>
<h1 class="title">We build<br><mark>fast sites & apps.</mark></h1>
<p class="text">Maximize your business potential...</p>
<a class="button" href="">Start project</a>
</div>
<img src="jam.svg" alt="" />
</div>
</div>
</section>
</BaseLayout>
Este es el aspecto de la página de inicio.
Puede ver la demostración aquí.
Obtención de datos en Astro
Si nos fijamos en el diseño de lo que estamos construyendo aquí, te darás cuenta de una sección de estudio de caso por debajo de la cabecera. En esta parte de nuestro tutorial, vamos a utilizar la API de Bejamas para obtener algunos datos del servidor y crear esas tarjetas de casos de estudio en nuestra página de inicio.
Obtener datos en Astro es muy fácil. Puedes usar la función global fetch()
en tus vallas de código para hacer peticiones HTTP a APIs en todos tus componentes.
En index.astro
, voy a añadir este código para obtener los datos de los casos de estudio desde el servidor utilizando la función fetch()
:
---
import BaseLayout from '../layouts/BaseLayout.astro';
const pageTitle = 'Bejamas';
const response = await fetch('bejamas.io/api/blog?category=case-studies');
const data = await response.json();
const posts = data.posts;
---
Ahora que tengo los datos disponibles en la variable posts, puedo usarla para generar HTML dinámico para mostrar las tarjetas de casos de estudio en mi página de inicio.
Este es el aspecto de la matriz posts
:
"posts": [
{
"excerpt": "",
"mainImage": {
"asset": {
"url": ""
}
},
"slug": "",
"title": ""
}
]
Voy a utilizar la función de map
para recorrer los puestos y crear cada tarjeta de forma dinámica de esta manera:
<section class="section" id="casestudies-section">
<div class="container">
<h2 class="section-title">Case studies</h2>
<ul class="case-studies">
{posts.map((post) => (
<li>
<article class="casestudy">
<img src={post.mainImage.asset.url} alt="" />
<div>
<h3>{post.title}</h3>
<p>{post.excerpt}</p>
<a href={`https://bejamas.io/blog/${post.slug}`} class="">Read more</a>
</div>
</article>
</li>
))}
</ul>
</div>
</section>
Lo mejor de todo es que todo esto ocurre en tiempo de compilación, y sólo enviaremos HTML estático al navegador.
Este es el resultado después de añadir estilo al CSS global:
Tu puedes ver la demo aquí
Gestión de contenidos en Astro
A la hora de crear y gestionar tus contenidos, Astro te ofrece dos opciones:
- Markdown
- MDX
MDX es similar al Markdown estándar pero con características adicionales. Te permite utilizar variables, expresiones JSX y componentes dentro de tu contenido Markdown.
Astro tiene soporte incorporado para Markdown, pero para trabajar con archivos .mdx
, necesitas instalar la integración @astrojs/mdx.
En este tutorial, nos ceñiremos al contenido Markdown estándar.
Antes de continuar, es importante mencionar que Astro v2 introdujo Content Collections
, que es una excelente manera de organizar tu contenido en un proyecto Astro.
Como dijimos antes, debido a cómo funciona el enrutamiento estático en Astro, cualquier entrada dentro del directorio src/pages/
obtiene una ruta. Esto significa que puedes abrirla en tu navegador o enlazarla en cualquier parte de tu proyecto. Además, sabemos que los archivos Markdown son un tipo de página en Astro que podemos colocar dentro de ese directorio.
Teniendo en cuenta esta información, vamos a crear nuestro primer contenido dentro del directorio src/pages.
Para ser más organizado, he creado una carpeta blog para mantener mis archivos .md
allí y he añadido mi primer contenido Markdown en ella:
Dado que los componentes Astro (.astro)
y los archivos Markdown (.md)
del directorio src/pages
se convierten automáticamente en páginas de tu sitio web, sólo tienes que navegar a la siguiente URL y visitar tu primera entrada del blog.
localhost:3000/blog/jamstack
Puedes añadir más información sobre tu contenido, como su título, fecha de publicación, imagen principal, etc. en la portada de tu Markdown como la siguiente:
---
title: 'Jamstack Explained'
pubDate: 2020-12-14
description: 'Jamstack is not about a specific technology…'
author: 'Denis Kostrzewa'
image:
url: 'https://bejamas.io/_next/image/?...'
alt: 'Jamstack Explained Photo'
---
# Jamstack explicado
Jamstack ya no es una palabra de moda por la que se pelean los desarrolladores. Se ha convertido en un floreciente ecosistema de herramientas que ayudan a los desarrolladores a crear sitios web de alto rendimiento, aplicaciones web progresivas y otros proyectos con ventajas demasiado buenas para ignorarlas.
Seguro que no quieres que tu entrada tenga ese aspecto y te gustaría incorporarle el diseño de tu sitio web, ¿verdad? Vamos a crear un diseño para el contenido de nuestro blog.
Añade un archivo llamado BlogLayout.astro
al directorio src/layouts
y copia y pega el siguiente código en él:
---
import Header from '../components/Header.astro';
import '../styles/global.css';
const { frontmatter } = Astro.props;
---
<html lang="en">
<head>
</head>
<body>
<Header />
<div class="container">
<div class="meta">
<div>
<time class="date">{frontmatter.pubDate.slice(0, 10)}</time>
<h1 class="title">{frontmatter.title}</h1>
<p class="description">{frontmatter.description}</p>
<span class="author">Author: <span class="author-name">{frontmatter.author}</span></span>
</div>
<img class="poster" src={frontmatter.image.url} alt={frontmatter.image.alt} />
</div>
<div class="body">
<slot />
</div>
</div>
</body>
</html>
Fíjate cómo pasamos las propiedades frontmatter
a esta plantilla usando Astro.props
. Ahora puedes añadir cualquiera de estas propiedades a tu plantilla de la forma que quieras.
Fíjate también en el elemento slot. Aquí es donde cualquier contenido por debajo del frontmatter
de tu archivo Markdown aparecerá en tu página HTML final.
Queda un paso más. Tenemos que añadir este diseño a nuestro contenido, así que volvemos a nuestro primer archivo Markdown y lo hacemos como el siguiente código:
---
layout: ../../layouts/BlogLayout.astro
title: 'Jamstack Explained'
pubDate: 2020-12-14
description: 'Jamstack is not about a specific technology…'
author: 'Denis Kostrzewa'
image:
url: 'https://bejamas.io/_next/image/?...'
alt: 'Jamstack Explained Photo'
---
# Jamstack explicado
Jamstack ya no es una palabra de moda por la que se pelean los desarrolladores. Se ha convertido en un floreciente ecosistema de herramientas que ayudan a los desarrolladores a crear sitios web de alto rendimiento, aplicaciones web progresivas y otros proyectos con ventajas demasiado buenas para ignorarlas.
Como puedes ver en la primera línea de código, Astro tiene una propiedad especial frontmatter layout para páginas Markdown. Esta propiedad define una ruta relativa a un componente de diseño de Astro.
Comprueba de nuevo la vista previa de tu navegador en localhost:3000/blog/jamstack
y mira lo que el diseño ha añadido a tu página.
Anidamiento de diseños
¿Te has dado cuenta de que, de nuevo, hemos tenido que añadir las etiquetas y a nuestro diseño BlogLayout.astro
? ¿No podemos simplemente usar nuestro BaseLayout
para esto?
Dado que los diseños Astor son básicamente componentes, podemos anidarlos. Así que todo lo que tenemos que hacer es añadir nuestro BaseLayout
al nuevo archivo BlogLayout.astro
:
---
import BaseLayout from "./BaseLayout.astro";
const { frontmatter } = Astro.props;
---
<BaseLayout pageTitle={frontmatter.title}>
<div class="container">
<div class="meta">
<div>
<time class="date">{frontmatter.pubDate.slice(0, 10)}</time>
<h1 class="title">{frontmatter.title}</h1>
<p class="description">{frontmatter.description}</p>
<span class="author">Author: <span class="author-name">{frontmatter.author}</span></span>
</div>
<img class="poster" src={frontmatter.image.url} alt={frontmatter.image.alt} />
</div>
<div class="body">
<slot />
</div>
</div>
</BaseLayout>
Qué bonito, ¿verdad?
Además, observa cómo pasamos el título de nuestra página para que sea el título de la página en nuestro BaseLayout
:
<BaseLayout pageTitle={frontmatter.title}>
Vamos a añadir algunos estilos al BlogLayout
para que se parezca más a nuestro post en Bejamas.io. Voy a añadir estilos de alcance al archivo BlogLayout.astro
:
---
import BaseLayout from "./BaseLayout.astro";
const { frontmatter } = Astro.props;
---
<style>
.container {
padding: 3rem 0;
max-width: 1152px;
}
.meta {
display: flex;
align-items: center;
justify-content: space-between;
gap: 2rem;
}
/* And more... */
</style>
<BaseLayout pageTitle={frontmatter.title}>
<!-- ... -->
</BaseLayout>
Este es el aspecto actual de las entradas del blog:
Lo último que tenemos que hacer es mostrar estas entradas en nuestra página de inicio.
Carga de archivos locales con Astro.glob()
Añade más entradas al directorio de tu blog, para que podamos crear una lista de ellas en nuestra página de inicio.
Astro.glob()
te permite cargar archivos locales en tu página estática. Devolverá un array de objetos, uno por cada entrada del blog, conteniendo toda la información sobre tus archivos Markdown.
Así es como puedes usarlo en tu archivo index.astro
:
---
const blogs = await Astro.glob('../pages/blog/*.md');
---
Para generar la lista completa de entradas dinámicamente, mapeamos sobre el array de blogs devuelto por Astro.glob()
como el siguiente código:
<section class="section blog-section" id="blog-section">
<div class="container">
<h2 class="section-title">Our Blog</h2>
<ul class="blogs">
{blogs.map((blog) =>
<li>
<article class="blog">
<img src={blog.frontmatter.image.url} alt="blog.frontmatter.image.alt" />
<h3>{blog.frontmatter.title}</h3>
<p>{blog.frontmatter.description}</p>
<a href={blog.url} class="">Read more</a>
</article>
</li>
)}
</ul>
</div>
</section>
Hemos añadido este archivo debajo de la sección de casos prácticos en nuestro archivo index.astro
.
Vuelve a visitar tu página de inicio en la vista previa de tu navegador y disfruta de tu lista de entradas de blog en la parte inferior de la página. Después de añadir algunos estilos al global.css
, este es el aspecto:
Añadir scripts en Astro
Puedes añadir interactividad a tus componentes Astro utilizando etiquetas HTML
<script>
console.log('Print this to the browser console');
</script>
<!-- relative path to script at `src/scripts/local.js` -->
<script src="../scripts/local.js"></script>
<!-- also works for local TypeScript files -->
<script src="./script-with-types.ts"></script>
<script is:inline src="https://my-extenrnal-script.com/script.js"></script>
Todos los scripts que añadas serán procesados y empaquetados en Astro y luego inyectados en el de tu página con type="module".
Si quieres evitar empaquetar el script, puedes usar la directiva is:inline
como ves en el último ejemplo de abajo que importa un archivo externo.
Cómo usar componentes de UI Framework en Astro
Una de las características más atractivas de Astro es su flexibilidad para integrarse con tus frameworks JS favoritos. Y no tienes que usar sólo un framework. Puedes trabajar con más de uno.
En nuestro proyecto, quería añadir una sección de preguntas frecuentes en la parte inferior de la página de inicio. No tenía mucho tiempo y quería utilizar el trabajo de otra persona para poder crear mi página lo antes posible. Busqué un componente FAQ React y aparecieron algunos enlaces.
Así es como puedes añadir un componente React a tu proyecto.
Primero, necesitas añadir React a tu proyecto. Ejecuta el siguiente comando en tu terminal:
npx astro add react
Puedes simplemente escribir tu propio componente React en tu proyecto añadiendo un archivo .jsx
en el directorio src/components.
Como quiero importar un componente React en lugar de escribirlo yo mismo, necesito añadirlo primero a mi proyecto.
Así que instalaré el paquete usando mi terminal:
npm install react-faq-component
Añadiremos los archivos FAQ.jsx
y FAQ.css
a mi directorio de componentes y personalizaré un poco el componente que he importado:
import React, { useEffect, useState } from 'react';
import Faq from 'react-faq-component';
import './FAQ.css';
const data = {
rows: [],
};
const styles = {};
const config = {};
export default function FAQ() {
return <div>
<Faq
data={data}
styles={styles}
config={config}
/>
</div>;
}
Una vez que tengas tu componente listo, necesitas importarlo a tu página:
---
import BaseLayout from '../layouts/BaseLayout.astro';
import Faq from '../components/FAQ.jsx';
const pageTitle = "Bejamas";
---
Y luego úsalo donde quieras en tu plantilla:
<section class="section" id="faq-section">
<h2 class="section-title">Questions you probably want to ask</h2>
<div class="container faq-container">
<Faq />
</div>
</section>
Este es el resultado:
Si compruebas la vista previa en el navegador, observarás que el componente se ha renderizado en su página. Sin embargo, no tienes interactividad. Como las acciones no funcionan, no puedes abrir los elementos cuando pulsas el botón.
Te mostraré lo que necesitamos en la siguiente sección.
Directivas en Astro
Como has visto en nuestro último ejemplo, el componente se añadió a la página, pero no funcionó. Esto ocurre porque, por defecto, los componentes de tu framework sólo se renderizarán en el servidor como HTML estático, por lo que, por ejemplo, tu manejador de clic o tus ganchos de estado no funcionarán. Esto es muy útil para añadir componentes que no son interactivos y evita enviar cualquier JavaScript innecesario al cliente.
Puedes hacer que un componente del framework sea interactivo (hidratado) añadiendo directivas Astro. Estos atributos de componente especifican cuando el JavaScript de tu componente debe ser enviado al navegador.
Voy a enumerar algunas de las directivas Astro aquí:
<Faq client:load />
Renderiza el componente al cargar la página.-
<Faq client:idle />
Renderiza el componente tan pronto como el navegador tiene algo de tiempo libre. <Faq client:visible />
muestra el componente sólo cuando se desplaza por la página.-
<Faq client:media="{media query here}" />
Renderiza el componente sólo si se aplica la consulta de medios. <Faq client:only="react" />
Sólo renderiza este componente en el cliente y no lo renderiza en el servidor en HTML estático.
Si no añades ninguno de estos elementos a tu componente, como en nuestro último ejemplo, se mostrará una versión sólo HTML del componente en el navegador, por lo que cualquier controlador de clic o estado no funcionará.
Quiero cargar mi componente FAQ al cargar la página, así que esto es lo que necesito:
<Faq client:load />
Construir y desplegar su proyecto Astro
Los sitios Astro son sitios estáticos desde el principio. Esto significa que todas las páginas son HTML estático al final. Así que tu primera opción para desplegar tu sitio si tienes un servidor es simplemente subir tus archivos HTML finales a tu servidor.
Antes de poder desplegar tu sitio web, necesitas construirlo. Para ello, tendrás que ejecutar el comando build
desde el directorio raíz de tu proyecto Astro. Puedes hacerlo ejecutando el siguiente comando en tu terminal:
npm run build
La compilación final de tu proyecto se almacenará en la carpeta dist por defecto. Por lo tanto, todo lo que necesitas hacer es subir tu directorio dist a tu servidor.
Desplegar manualmente tu sitio web no es el método preferido hoy en día. Hay un montón de herramientas y servicios que automatizan todo el flujo de trabajo para ti.
Todo lo que necesitas hacer es empujar tus cambios, y ellos construirán y desplegarán el proyecto por ti.
Puedes seguir las guías en el sitio web de Astro para ver cómo puedes desplegar tu proyecto en diferentes servicios de despliegue como Netlify, Vercel, Deno, etc.
Conclusión
En conclusión, el auge de los frameworks de JavaScript nos ha dado, como desarrolladores web, mucho poder y ricas experiencias. Nos encanta usar estos frameworks porque facilitan la creación de componentes, compartirlos y reutilizarlos.
Las herramientas en torno a la construcción con frameworks como Vue, React y Svelte son de primera categoría. Sin embargo, el coste de utilizar estos frameworks es a menudo el envío de una gran cantidad de JavaScript con nuestras páginas, incluso para el contenido estático simple.
Con Astro, obtenemos los beneficios de ambos mundos. Podemos seguir escribiendo contenido dinámico utilizando JSX y JavaScript, pero Astro lo renderiza todo en HTML estático, de modo que sólo cargamos el JavaScript que realmente necesitamos.
De este modo, nuestros usuarios disfrutan de una experiencia rápida y fluida, mientras que nosotros seguimos disfrutando de todas las ventajas de trabajar con frameworks dinámicos. Los usuarios y los desarrolladores salen ganando.