Pular para o conteúdo

Layouts

Layouts são componentes Astro usados para fornecer uma estrutura de UI reutilizável, como um template de página.

Convencionalmente, usamos o termo “layout” para componentes Astro que fornecem elementos comuns de UI compartilhados entre páginas, como cabeçalhos, barras de navegação e rodapés. Um componente de layout Astro típico fornece às páginas Astro, Markdown ou MDX:

  • uma estrutura de página (tags <html>, <head> e <body>)
  • um <slot /> para especificar onde o conteúdo individual da página deve ser inserido.

Porém, não há nada de especial em componentes de layout! Eles podem receber props e importar e usar outros componentes como qualquer outro componente Astro. Eles podem incluir componentes de frameworks de UI (EN) e scripts no lado do cliente (EN). Eles nem precisam fornecer uma estrutura de página completa e podem ser usados como templates parciais de UI.

No entanto, se um componente de layout contiver uma estrutura de página, seu elemento <html> deverá ser o pai de todos os outros elementos do componente.

Componentes de layout são normalmente colocados em um diretório src/layouts no seu projeto para organização, mas isso não é obrigatório; você pode colocá-los onde preferir. Você pode até manter os componentes de layout junto às suas páginas ao prefixar os nomes dos layouts com _ (EN).

src/layouts/LayoutDoMeuSite.astro
---
import HeadBase from '../components/HeadBase.astro';
import Rodape from '../components/Rodape.astro';
const { titulo } = Astro.props;
---
<html lang="pt-BR">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<HeadBase titulo={titulo}/>
</head>
<body>
<nav>
<a href="#">Início</a>
<a href="#">Postagens</a>
<a href="#">Contato</a>
</nav>
<h1>{titulo}</h1>
<article>
<slot /> <!-- seu conteúdo é injetado aqui -->
</article>
<Rodape />
</body>
<style>
h1 {
font-size: 2rem;
}
</style>
</html>
src/pages/index.astro
---
import LayoutDoMeuSite from '../layouts/LayoutDoMeuSite.astro';
---
<LayoutDoMeuSite titulo="Página Inicial">
<p>Conteúdo da minha página, envolto em um layout!</p>
</LayoutDoMeuSite>
Aprenda mais sobre slots.

Qualquer layout Astro pode ser modificado para introduzir segurança de tipos e preenchimento automático ao fornecer os tipos de suas props:

src/components/MeuLayout.astro
---
interface Props {
titulo: string;
descricao: string;
dataPublicacao: string;
numeroVisualizacoes: number;
}
const { titulo, descricao, dataPublicacao, numeroVisualizacoes } = Astro.props;
---
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="description" content={descricao}>
<title>{titulo}</title>
</head>
<body>
<header>
<p>Publicado em {dataPublicacao}</p>
<p>Visualizado por {numeroVisualizacoes} pessoas</p>
</header>
<main>
<slot />
</main>
</body>
</html>

Layouts de página são especialmente úteis para páginas Markdown individuais que, de outra forma, não teriam nenhuma formatação.

O Astro fornece uma propriedade especial layout no frontmatter destinada a arquivos .md individuais localizados em src/pages/ que usam roteamento baseado em arquivos (EN). Essa propriedade especifica qual componente .astro deve ser usado como layout da página. O componente permite fornecer conteúdo para o <head>, como metatags (por exemplo, <meta charset="utf-8">) e estilos para a página Markdown. Por padrão, esse componente especificado pode acessar automaticamente os dados do arquivo Markdown.

Essa propriedade não é reconhecida como especial ao usar coleções de conteúdo (EN) para consultar e renderizar seu conteúdo.

src/pages/pagina.md
---
layout: ../layouts/LayoutPostagemBlog.astro
titulo: "Olá, Mundo!"
autor: "Matthew Phillips"
data: "09 Ago 2022"
---
Todas as propriedades do frontmatter estão disponíveis como props para um componente de layout Astro.
A propriedade `layout` é a única propriedade especial fornecida pelo Astro.
Você pode usá-la em arquivos Markdown localizados em `src/pages/`.

Um layout típico para uma página Markdown inclui:

  1. A prop frontmatter para acessar o frontmatter da página Markdown e outros dados.
  2. Um <slot /> padrão para indicar onde o conteúdo Markdown da página deve ser renderizado.
src/layouts/LayoutPostagemBlog.astro
---
// 1. A prop frontmatter dá acesso ao frontmatter e a outros dados
const { frontmatter } = Astro.props;
---
<html>
<head>
<!-- Adicione outros elementos de head aqui, como estilos e metatags. -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8">
<title>{frontmatter.titulo}</title>
</head>
<body>
<!-- Adicione outros componentes de UI aqui, como cabeçalhos e rodapés comuns. -->
<h1>{frontmatter.titulo} por {frontmatter.autor}</h1>
<!-- 2. O HTML renderizado será passado para o slot padrão. -->
<slot />
<p>Escrito em: {frontmatter.data}</p>
</body>
</html>

Você pode definir o tipo Props (EN) de um layout com o tipo utilitário MarkdownLayoutProps:

src/layouts/LayoutPostagemBlog.astro
---
import type { MarkdownLayoutProps } from 'astro';
type Props = MarkdownLayoutProps<{
// Defina as props do frontmatter aqui
titulo: string;
autor: string;
data: string;
}>;
// Agora, `frontmatter`, `url` e outras propriedades do layout Markdown
// são acessíveis com segurança de tipos
const { frontmatter, url } = Astro.props;
---
<html>
<head>
<meta charset="utf-8">
<link rel="canonical" href={new URL(url, Astro.site).pathname}>
<title>{frontmatter.titulo}</title>
</head>
<body>
<h1>{frontmatter.titulo} por {frontmatter.autor}</h1>
<slot />
<p>Escrito em: {frontmatter.data}</p>
</body>
</html>

Um layout Markdown terá acesso às seguintes informações por meio de Astro.props:

  • file - O caminho absoluto desse arquivo (por exemplo, /home/usuario/projetos/.../arquivo.md).
  • url - A URL da página (por exemplo, /pt-br/guides/markdown-content).
  • frontmatter - Todo o frontmatter do documento Markdown ou MDX.
    • frontmatter.file - O mesmo que a propriedade de nível superior file.
    • frontmatter.url - O mesmo que a propriedade de nível superior url.
  • headings - Uma lista dos títulos (h1 -> h6) do documento Markdown ou MDX e seus metadados associados. Essa lista segue o tipo { depth: number; slug: string; text: string }[].
  • rawContent() - Uma função que retorna o documento Markdown bruto como uma string.
  • compiledContent() - Uma função assíncrona que retorna o documento Markdown compilado como uma string de HTML.

Você também pode usar a propriedade especial de layout Markdown no frontmatter de arquivos MDX para passar as props frontmatter e headings diretamente a um componente de layout especificado, da mesma maneira.

Para passar ao seu layout MDX informações que não existem (ou não podem existir) no frontmatter, você pode importar e usar um componente <Layout />. Ele funciona como qualquer outro componente Astro e não recebe nenhuma prop automaticamente. Passe diretamente todas as props necessárias:

src/pages/postagens/primeira-postagem.mdx
---
layout: ../../layouts/LayoutBase.astro
title: 'Minha primeira postagem MDX'
publishDate: '21 de Setembro de 2022'
---
import LayoutBase from '../../layouts/LayoutBase.astro';
export function utilitarioSofisticadoJS() {
return 'Tenta fazer isso com YAML!';
}
<LayoutBase title={frontmatter.title} utilitarioSofisticadoJS={utilitarioSofisticadoJS}>
Bem-vindo ao meu novo blog Astro, usando MDX!
</LayoutBase>

Em seguida, seus valores estarão disponíveis por meio de Astro.props no layout, e o conteúdo MDX será inserido na página onde o componente <slot /> estiver escrito:

src/layouts/LayoutBase.astro
---
const { title, utilitarioSofisticadoJS } = Astro.props;
---
<html>
<head>
<!-- -->
<meta charset="utf-8">
</head>
<body>
<!-- -->
<h1>{title}</h1>
<slot /> <!-- seu conteúdo é inserido aqui -->
<p>{utilitarioSofisticadoJS()}</p>
<!-- -->
</body>
</html>

Ao usar qualquer layout (pela propriedade layout do frontmatter ou pela importação de um layout), inclua a tag <meta charset="utf-8"> no layout, pois o Astro não a adicionará mais automaticamente à sua página MDX.

Saiba mais sobre o suporte do Astro a Markdown e MDX em nosso guia de Markdown (EN).

Componentes de layout não precisam conter uma página inteira de HTML. Você pode separar seus layouts em componentes menores e combiná-los para criar templates de página ainda mais flexíveis. Esse padrão é útil quando você quer compartilhar algum código através de múltiplos layouts.

Por exemplo, um componente de layout LayoutPostagemBlog.astro pode estilizar o título, a data e o autor de uma postagem. Então, um LayoutBase.astro de todo o site poderia lidar com o resto do template da sua página, como navegação, rodapés, metatags de SEO, estilos globais e fontes. Você também pode passar props recebidas da sua postagem para outro layout, assim como em qualquer outro componente aninhado.

src/layouts/LayoutPostagemBlog.astro
---
import LayoutBase from './LayoutBase.astro';
const { frontmatter } = Astro.props;
---
<LayoutBase url={frontmatter.url}>
<h1>{frontmatter.titulo}</h1>
<h2>Autor da postagem: {frontmatter.autor}</h2>
<slot />
</LayoutBase>
Contribua Comunidade Patrocine