Saltar al contenido

Layouts

Los layouts son componentes de Astro que se utilizan para proporcionar una estructura de interfaz de usuario reutilizable, como la plantilla de una página.

Por convención, utilizamos el término "layout" para los componentes de Astro que proporcionan elementos de interfaz de usuario comunes compartidos entre páginas, como encabezados, barras de navegación y pies de página. Un componente de layout típico de Astro proporciona a las páginas de Astro, Markdown o MDX lo siguiente:

  • una estructura de la página (page shell) (etiquetas <html>, <head> y <body>)
  • un <slot /> para especificar dónde debe inyectarse el contenido de cada página individual.

¡Pero no hay nada de especial en un componente de layout! Pueden aceptar props e importar y utilizar otros componentes como cualquier otro componente de Astro. Pueden incluir componentes de frameworks de UI y scripts del lado del cliente. Ni siquiera tienen que proporcionar una estructura de página completa, y en su lugar pueden utilizarse como plantillas de interfaz de usuario parciales.

Sin embargo, si un componente de layout contiene una estructura de página (page shell), su elemento <html> debe ser el padre de todos los demás elementos del componente.

Los componentes de layout se suelen colocar en el directorio src/layouts de tu proyecto para organizarlos, pero esto no es un requisito; puedes optar por colocarlos en cualquier lugar de tu proyecto. Incluso puedes colocar componentes de layout junto a tus páginas prefijando los nombres de los layouts con _.

src/layouts/MySiteLayout.astro
---
import BaseHead from '../components/BaseHead.astro';
import Footer from '../components/Footer.astro';
const { title } = Astro.props;
---
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<BaseHead title={title}/>
</head>
<body>
<nav>
<a href="#">Home</a>
<a href="#">Posts</a>
<a href="#">Contact</a>
</nav>
<h1>{title}</h1>
<article>
<slot /> <!-- your content is injected here -->
</article>
<Footer />
</body>
<style>
h1 {
font-size: 2rem;
}
</style>
</html>
src/pages/index.astro
---
import MySiteLayout from '../layouts/MySiteLayout.astro';
---
<MySiteLayout title="Home Page">
<p>My page content, wrapped in a layout!</p>
</MySiteLayout>
Aprende más sobre los slots.

Cualquier layout de Astro se puede modificar para introducir seguridad de tipos y autocompletado proporcionando los tipos para tus props:

src/components/MyLayout.astro
---
interface Props {
title: string;
description: string;
publishDate: string;
viewCount: number;
}
const { title, description, publishDate, viewCount } = Astro.props;
---
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="description" content={description}>
<title>{title}</title>
</head>
<body>
<header>
<p>Published on {publishDate}</p>
<p>Viewed by {viewCount} folks</p>
</header>
<main>
<slot />
</main>
</body>
</html>

Los layouts de página son especialmente útiles para páginas individuales de Markdown que, de otro modo, no tendrían ningún formato de página.

Astro proporciona una propiedad especial de frontmatter layout destinada a archivos .md individuales ubicados dentro de src/pages/ que utilizan enrutamiento basado en archivos para especificar qué componente .astro utilizar como layout de página. Este componente te permite proporcionar contenido de <head> como etiquetas meta (p. ej., <meta charset="utf-8">) y estilos para la página de Markdown. Por defecto, este componente especificado puede acceder automáticamente a los datos del archivo Markdown.

Esto no se reconoce como una propiedad especial cuando se utilizan colecciones de contenido para consultar y renderizar tu contenido.

src/pages/page.md
---
layout: ../layouts/BlogPostLayout.astro
title: "Hello, World!"
author: "Matthew Phillips"
date: "09 Aug 2022"
---
All frontmatter properties are available as props to an Astro layout component.
The `layout` property is the only special one provided by Astro.
You can use it in Markdown files located within `src/pages/`.

Un layout típico para una página de Markdown incluye:

  1. La prop frontmatter para acceder al frontmatter de la página de Markdown y otros datos.
  2. Un <slot /> predeterminado para indicar dónde debe renderizarse el contenido de Markdown de la página.
src/layouts/BlogPostLayout.astro
---
// 1. The frontmatter prop gives access to frontmatter and other data
const { frontmatter } = Astro.props;
---
<html>
<head>
<!-- Add other Head elements here, like styles and meta tags. -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8">
<title>{frontmatter.title}</title>
</head>
<body>
<!-- Add other UI components here, like common headers and footers. -->
<h1>{frontmatter.title} by {frontmatter.author}</h1>
<!-- 2. Rendered HTML will be passed into the default slot. -->
<slot />
<p>Written on: {frontmatter.date}</p>
</body>
</html>

Puedes establecer el tipo de tipo Props de un layout con el ayudante MarkdownLayoutProps:

src/layouts/BlogPostLayout.astro
---
import type { MarkdownLayoutProps } from 'astro';
type Props = MarkdownLayoutProps<{
// Define frontmatter props here
title: string;
author: string;
date: string;
}>;
// Now, `frontmatter`, `url`, and other Markdown layout properties
// are accessible with type safety
const { frontmatter, url } = Astro.props;
---
<html>
<head>
<meta charset="utf-8">
<link rel="canonical" href={new URL(url, Astro.site).pathname}>
<title>{frontmatter.title}</title>
</head>
<body>
<h1>{frontmatter.title} by {frontmatter.author}</h1>
<slot />
<p>Written on: {frontmatter.date}</p>
</body>
</html>

Un layout de Markdown tendrá acceso a la siguiente información a través de Astro.props:

  • file - La ruta absoluta de este archivo (p. ej., /home/user/projects/.../file.md).
  • url - La URL de la página (p. ej., /es/guides/markdown-content).
  • frontmatter - All frontmatter from the Markdown or MDX document.
    • frontmatter.file - Lo mismo que la propiedad de nivel superior file.
    • frontmatter.url - Lo mismo que la propiedad de nivel superior url.
  • headings - Una lista de encabezados (h1 -> h6) en el documento Markdown o MDX con metadatos asociados. Esta lista sigue el tipo: { depth: number; slug: string; text: string }[].
  • rawContent() - Una función que devuelve el documento de Markdown sin procesar como una cadena de texto.
  • compiledContent() - Una función asíncrona que devuelve el documento de Markdown compilado como una cadena de texto HTML.

También puedes usar la propiedad especial de layout de Markdown en el frontmatter de los archivos MDX para pasar las props frontmatter y headings directamente a un componente de layout especificado de la misma manera.

Para pasar información a tu layout de MDX que no existe (o no puede existir) en tu frontmatter, en su lugar puedes importar y usar un componente <Layout />. Esto funciona como cualquier otro componente de Astro y no recibirá ninguna prop de forma automática. Pásale directamente cualquier prop necesaria:

src/pages/posts/first-post.mdx
---
layout: ../../layouts/BaseLayout.astro
title: 'My first MDX post'
publishDate: '21 September 2022'
---
import BaseLayout from '../../layouts/BaseLayout.astro';
export function fancyJsHelper() {
return "Try doing that with YAML!";
}
<BaseLayout title={frontmatter.title} fancyJsHelper={fancyJsHelper}>
Welcome to my new Astro blog, using MDX!
</BaseLayout>

Luego, tus valores estarán disponibles para ti a través de Astro.props en tu layout, y tu contenido de MDX se inyectará en la página donde está escrito tu componente <slot />:

src/layouts/BaseLayout.astro
---
const { title, fancyJsHelper } = Astro.props;
---
<html>
<head>
<!-- -->
<meta charset="utf-8">
</head>
<body>
<!-- -->
<h1>{title}</h1>
<slot /> <!-- your content is injected here -->
<p>{fancyJsHelper()}</p>
<!-- -->
</body>
</html>

Al usar cualquier layout (ya sea a través de la propiedad de frontmatter layout o importando un layout), debes incluir la etiqueta <meta charset="utf-8"> en tu layout, ya que Astro ya no la agregará automáticamente a tu página de MDX.

Aprende más sobre el soporte de Markdown y MDX de Astro en nuestra guía de Markdown.

Los componentes de layout no necesitan contener un HTML de una página completa. Puedes dividir tus layouts en componentes más pequeños y combinar componentes de layout para crear plantillas de página aún más flexibles. Este patrón es útil cuando deseas compartir algún código en múltiples layouts.

Por ejemplo, un componente de layout BlogPostLayout.astro podría dar estilo al título, la fecha y el autor de una publicación. Luego, un BaseLayout.astro para todo el sitio podría encargarse del resto de la plantilla de tu página, como la navegación, los pies de página, las etiquetas meta de SEO, los estilos globales y las fuentes. También puedes pasar las props recibidas de tu publicación a otro layout, al igual que cualquier otro componente anidado.

src/layouts/BlogPostLayout.astro
---
import BaseLayout from './BaseLayout.astro';
const { frontmatter } = Astro.props;
---
<BaseLayout url={frontmatter.url}>
<h1>{frontmatter.title}</h1>
<h2>Post author: {frontmatter.author}</h2>
<slot />
</BaseLayout>
Contribuir Comunidad Patrocinar