Layouts and Shared UI
Wrapping pages in a shared Layout component instead of repeating boilerplate HTML.
អាន 2 នាទី
Every page in a site tends to share the same skeleton — the <html>/<head> boilerplate, a <meta charset> tag, a navigation bar, a footer. Copy-pasting that into every .astro page file works, but the moment you need to change the footer, you're editing every page. Layouts solve this the same way any component solves duplication: pull the shared part into one place.
A basic layout
A layout is just an ordinary .astro component, conventionally kept in src/layouts/, that uses <slot /> to mark where page-specific content should go.
---
// src/layouts/BaseLayout.astro
interface Props {
title: string;
}
const { title } = Astro.props;
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>{title}</title>
</head>
<body>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
<main>
<slot />
</main>
<footer>
<p>© 2026 My Site</p>
</footer>
</body>
</html>Using the layout in a page
A page imports the layout, wraps its content with it, and passes any props the layout expects — here, title:
---
// src/pages/about.astro
import BaseLayout from "../layouts/BaseLayout.astro";
---
<BaseLayout title="About Us">
<h1>About Us</h1>
<p>We build things with Astro.</p>
</BaseLayout>Everything between <BaseLayout> and </BaseLayout> renders where <slot /> sits inside BaseLayout.astro. The page itself no longer contains <html>, <head>, or the navigation bar at all — it only describes what's unique about that one page, and the layout supplies everything shared.
Nesting layouts
Layouts can wrap other layouts, which is useful when a section of a site needs extra shared structure on top of the base shell — a blog post layout that adds a byline and publish date on top of the site-wide BaseLayout:
---
// src/layouts/BlogPostLayout.astro
import BaseLayout from "./BaseLayout.astro";
interface Props {
title: string;
publishDate: string;
}
const { title, publishDate } = Astro.props;
---
<BaseLayout title={title}>
<article>
<p><em>Published {publishDate}</em></p>
<slot />
</article>
</BaseLayout>Now a blog post page wraps its content in BlogPostLayout, which in turn wraps everything in BaseLayout — each layer adding exactly the structure relevant to it, without duplicating what the layer below already provides.
Why this matters beyond convenience
Layouts aren't just about avoiding repetition — they're where site-wide concerns (SEO meta tags, a shared analytics script, global stylesheet imports, the <html lang> attribute) live in exactly one place, so getting them right once means getting them right everywhere. Any change to how every page starts and ends happens in a single file, not scattered across dozens of pages.