A Component That Wraps Pages Through `<slot />`
Layouts
A layout is just a component that defines the shared chrome — `<head>`, header, footer — and renders the page in a `<slot />`.
What you'll learn
- Author a layout
- Use it from a page via frontmatter import
- Pass per-page metadata as props
A layout isn’t a special API — it’s just an Astro component
that you wrap a page in. By convention they live in src/layouts/.
A Tiny Layout
---
// src/layouts/Base.astro
interface Props {
title: string;
}
const { title } = Astro.props;
---
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>{title}</title>
</head>
<body>
<header><a href="/">Home</a></header>
<main>
<slot />
</main>
<footer>© 2026 Astro</footer>
</body>
</html> Use It From a Page
---
// src/pages/about.astro
import Base from "../layouts/Base.astro";
---
<Base title="About">
<h1>About Us</h1>
<p>Hello!</p>
</Base> Whatever the page puts inside <Base> renders where the layout has
<slot />. The page is responsible only for its content — the
layout owns the chrome.
Passing Metadata
The layout decides what props it accepts. Common pattern: title, description, OG image:
---
// src/layouts/Base.astro
interface Props {
title: string;
description?: string;
ogImage?: string;
}
const { title, description = "", ogImage } = Astro.props;
---
<head>
<title>{title}</title>
{description && <meta name="description" content={description} />}
{ogImage && <meta property="og:image" content={ogImage} />}
</head> Markdown Pages
A .md or .mdx file in src/pages/ can declare a layout in its
frontmatter:
---
layout: ../layouts/Base.astro
title: Welcome
---
# Hello, Markdown The Markdown rendered to HTML lands in the layout’s <slot />. The
layout receives the markdown’s frontmatter via Astro.props.
Up Next
Layouts can wrap other layouts — composing UI in layers.
Nested Layouts →