00:00 / 00:00
04. Definiendo el layout
Si abrimos la página index.astro
, podemos ver que trae todo lo típico de una página HTML, con su head
, body
, etc.
Si vas a crear un sitio web, lo normal es que todas las páginas tengan una estructura similar, con una cabecera y un pie de página, si estuvieramos trabajando en modo estático hacer esto sin ningún tipo de ayuda, sería un poco tedioso, ya que tendríamos que repetir el código de la cabecera y el pie en cada una de las páginas.
Vamos a ver como resolver esto en Astro, creamos un layout, y le indicamos donde está el slot
que es el sitio en el que se va a renderizar el contenido de cada página.
./src/layouts/Layout.astro
---
// Nos traemos también los estilos globales (tailwind)
import "../styles/global.css";
---
<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>Astro</title>
</head>
<body>
<slot />
</body>
</html>
Antes de continuar, vamos a resaltar varios puntos importantes:
Si te fijas al principio hay un código "entre rejas" (
---
), esto es un bloque de código que se ejecuta en el servidor, y es donde podemos importar componentes, definir variables, etc. Si estamos en modo SSG (Static Site Generation), este bloque se ejecuta una sóla vez cuando hagamos el build del sitio, y el resultado se guarda en un archivo HTML estático. Si estamos en modo SSR (Server Side Rendering), este bloque se ejecuta cada vez que se solicita la página al servidor.El tag
<slot />
es un marcador de posición donde se insertará el contenido de cada página que use este layout. Es como un espacio reservado para el contenido específico de cada página, si trabajas con React, es similar a los children de un componente, si vienes de Vue, es similar a los slots de Vue, y si eres de Angular es similar a los ng-content.
Y nuestro index.astro
quedaría así:
./src/pages/index.astro
---
import Layout from "../layouts/Layout.astro";
---
<Layout>
<h1>Astro</h1>
</Layout>
Fijate que hemos importado el layout y lo hemos usado como un componente, envolviendo el contenido de la página dentro de él. Esto hace que el contenido del h1
se renderice en el lugar del <slot />
del layout.
Vamos a ver que esto sigue funcionando.
npm run dev
Hay una cosa que te puede chirriar y es que el title de la página siempre es Astro, ¿No estaría bien poder alimentarle por una propiedad del componente el título?
Para ello podemos definir propiedades en el layout, de forma que podamos personalizarlo desde cada página, esto es parecido a las props de un componente en React.
./src/Layout.astro
---
// Nos traemos también los estilos globales (tailwind)
import "../styles/global.css";
+ interface Props {
+ title: string;
+ }
+
+ const { title } = Astro.props;
---
<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>Astro</title>
+ <title>{title}</title>
Y en Index.astro, ponemos el título que queramos:
./src/pages/index.astro
- <Layout>
+ <Layout title="Campus">
- <h1>Astro</h1>
+ <h1>Listado de Cursos</h1>
</Layout>
Ya que estamos, vamos a añadir un componente de cabecera, que muestre el texto "Online Campus" (aquí en un futuro podría ir un menú de navegación, o un logo, etc.).
./src/components/Header.astro
---
---
<header class="bg-white shadow-sm">
<div class="max-w-7xl mx-auto px-4 py-6 sm:px-6 lg:px-8">
<h1 class="text-3xl font-bold text-gray-800">Online Campus</h1>
</div>
</header>
Y lo usamos en nuestro layout:
./src/layouts/Layout.astro
---
// IMPORTANTE Mencionar esto !!
import "../styles/global.css";
+ import Header from "../components/Header.astro";
interface Props {
title: string;
}
const { title } = Astro.props;
---
<html lang="en">
// (...)
<body>
+ <Header />
<slot />
</body>
</html>
Ahora tenemos una cabecera que se muestra en todas las páginas que usen este layout.
En el próximo vídeo, veremos que es un Headless CMS, que ventaja nos aporta, y haremos el setup en el proyecto de Content Island, un HCMS que nos permitirá gestionar el contenido de nuestro sitio web de forma sencilla y eficiente.