Skip to content

Astro Layouts — Reusable Page Structure

DodaTech Updated 2026-06-28 3 min read

Learn how to create Astro layouts with slots, pass props, nest layouts, and compose reusable page shells across your entire website.

In this lesson, you'll create layout components that wrap page content using the <slot /> element, pass props for dynamic metadata, and nest layouts for multi-level structure. Layouts in Astro are just components that accept children.

What You'll Learn

How to create base layouts, use named slots, pass props for SEO and styling, and nest layout components for complex page hierarchies.

Why It Matters

Layouts eliminate repetitive HTML structure across pages. A single layout change updates every page that uses it, saving hours of maintenance.

Real-World Use

DodaTech's tutorial platform uses a three-level layout system: base HTML shell, content sidebar layout, and lesson-specific layout with navigation.

flowchart TD
    A[BaseLayout] --> B[DocLayout]
    A --> C[BlogLayout]
    B --> D[LessonLayout]
    B --> E[GuideLayout]
    style A fill:#ff5a03,color:#fff

Creating a Layout

A layout is a component that wraps page content using <slot />:

---
// src/layouts/BaseLayout.astro
export interface Props {
  title: string;
  description?: string;
}
const { title, description } = Astro.props;
---
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>{title}</title>
  {description && <meta name="description" content={description} />}
</head>
<body>
  <nav>
    <a href="/">Home</a>
    <a href="/blog">Blog</a>
  </nav>
  <main>
    <slot />
  </main>
  <footer>Built by DodaTech</footer>
</body>
</html>

Using the layout in a page:

---
import BaseLayout from "../layouts/BaseLayout.astro";
---
<BaseLayout title="Home" description="Welcome to my site">
  <h1>Home Page</h1>
  <p>This content appears inside the <main> element.</p>
</BaseLayout>

Output: The page renders the full HTML shell with nav, footer, and the page content injected into the slot.

Named Slots

Use named slots for multiple injection points:

---
// src/layouts/DocLayout.astro
export interface Props {
  title: string;
}
const { title } = Astro.props;
---
<BaseLayout {title}>
  <aside>
    <slot name="sidebar" />
  </aside>
  <article>
    <slot />
  </article>
</BaseLayout>

Page using named slots:

---
import DocLayout from "../layouts/DocLayout.astro";
---
<DocLayout title="Getting Started">
  <nav slot="sidebar">
    <a href="/intro">Intro</a>
    <a href="/setup">Setup</a>
  </nav>
  <h1>Getting Started</h1>
  <p>Main content goes here.</p>
</DocLayout>

Output: The sidebar nav appears in the <aside> slot, and the main content fills the default slot inside the <article>.

Nested Layouts

Layouts can wrap other layouts:

---
// src/layouts/BlogLayout.astro
import BaseLayout from "./BaseLayout.astro";
const { title } = Astro.props;
---
<BaseLayout {title}>
  <header>
    <h1>{title}</h1>
  </header>
  <slot />
</BaseLayout>

Pages use BlogLayout directly, which automatically applies BaseLayout underneath.

Common Mistakes

  1. Forgetting to import the layout: Layouts must be imported in every page that uses them. They are not auto-loaded.
  2. Using multiple default slots: A layout can have only one unnamed <slot />. Use named slots for additional injection points.
  3. Passing too many props: Keep layout props focused on structure and metadata. Page-specific data belongs in the page component.
  4. Not wrapping the slot in semantic HTML: The <slot /> can appear anywhere. Wrap it in <main>, <article>, or <section> for Accessibility.
  5. Nesting layouts too deeply: More than 3 levels of layout nesting makes the component hierarchy hard to follow.

Practice Questions

  1. What element does a layout use to render page content? Answer: The <slot /> element. It marks where child content is inserted.

  2. How do you pass data from a page to its layout? Answer: Through component props. Define props in the layout's frontmatter and pass them when using the layout component.

  3. What is a named slot used for? Answer: Multiple injection points in a layout. The slot="name" attribute on the child targets a specific <slot name="name" /> in the layout.

  4. Can a layout use another layout? Answer: Yes. Layouts can import and wrap other layouts, creating a nesting hierarchy.

Challenge

Build a three-level layout system: BaseLayout (HTML shell), PageLayout (header + sidebar + content), and BlogPostLayout (adds author bio and comments section). Apply BlogPostLayout to a markdown-based blog post page.

Mini Project

Create a documentation layout with a sidebar navigation using named slots. The sidebar should list links, and the main content area renders the page.

FAQ

Can I use multiple layouts on one page?

: No. A page can only use one layout component. Nest layouts inside each other for multi-level structure.

Do layouts support TypeScript?

: Yes. Define props with export interface Props in the layout's frontmatter.

Can a layout include interactive components?

: Yes. Add client:* directives to interactive components in layouts, just like in pages.

Are layouts re-rendered on navigation?

: In static output, no. Each page is a separate HTML file. In SSR mode, layouts re-render per request.

What's Next

Learn how Astro Components provide reusable UI building blocks beyond layouts.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro