Lesson 5: Layouts & Reusable Page Structures

❌ The Problem Without Layouts

Imagine you have 10 pages on your site. Each page needs:

Bad approach: Copy-paste this code on every page.

Issues with copy-pasting:

✅ The Solution: Layouts

Layouts are components that wrap your page content. You define the common structure ONCE, then reuse it everywhere.

Think of it like this:

🖼️ Picture Frame

Frame = Layout (stays same)

Picture = Content (changes)

📄 Letter Template

Header/Footer = Layout

Letter content = Your page

🏠 House Structure

Foundation/Walls = Layout

Furniture = Your content

🔧 How Layouts Work

Step 1: Create a Layout Component

Put it in src/layouts/

src/layouts/BaseLayout.astro

Step 2: Use <slot />

The <slot /> is where your page content goes

<!-- Layout structure -->
<header>Nav here</header>
<main>
  <slot /> <!-- Page content goes here -->
</main>
<footer>Footer here</footer>

Step 3: Wrap Your Pages

Import and use the layout on your pages

---
import BaseLayout from '../layouts/BaseLayout.astro';
---

<BaseLayout>
  <h1>My Page Content</h1>
  <p>This goes in the slot!</p>
</BaseLayout>

Result:

Astro takes your page content and inserts it where the <slot /> is in the layout!

🎯 Understanding <slot />

<slot /> is a placeholder for your page content.

Layout file:

<!-- BaseLayout.astro -->
<html>
  <body>
    <nav>Navigation</nav>
    <main>
      <slot /> <!-- Content goes here -->
    </main>
    <footer>Footer</footer>
  </body>
</html>

Page file:

<!-- about.astro -->
---
import BaseLayout from '../layouts/BaseLayout.astro';
---

<BaseLayout>
  <h1>About Page</h1>
  <p>This is the about page content.</p>
</BaseLayout>

Final HTML output:

<html>
  <body>
    <nav>Navigation</nav>
    <main>
      <h1>About Page</h1>
      <p>This is the about page content.</p>
    </main>
    <footer>Footer</footer>
  </body>
</html>

💡 The <h1> and <p> from your page replaced the <slot /> in the layout!

🎨 Layouts Can Accept Props!

Just like components, layouts can receive props to customize behavior.

Layout with props:

<!-- BaseLayout.astro -->
---
const { title, description } = Astro.props;
---

<html>
  <head>
    <title>{title}</title>
    <meta name="description" content={description} />
  </head>
  <body>
    <main>
      <slot />
    </main>
  </body>
</html>

Using the layout with props:

<!-- about.astro -->
---
import BaseLayout from '../layouts/BaseLayout.astro';
---

<BaseLayout
  title="About Me"
  description="Learn about my creative journey"
>
  <h1>About Page Content</h1>
</BaseLayout>

Common layout props:

📚 You Can Have Multiple Layouts

Different sections of your site might need different layouts.

BaseLayout.astro

For regular pages (home, about, contact)

  • Header with nav
  • Main content area
  • Footer

BlogLayout.astro

For blog posts

  • Header with nav
  • Article metadata (date, author)
  • Table of contents
  • Main content
  • Related posts
  • Footer

ProjectLayout.astro

For portfolio projects

  • Minimal header
  • Full-width hero image
  • Project details
  • Image gallery
  • Back to projects link

🪆 Nested Layouts (Advanced)

You can wrap a layout inside another layout!

Example structure:

BaseLayout (HTML structure, nav, footer)
  └─ BlogLayout (blog-specific features)
      └─ Your blog post content

How it works:

<!-- BaseLayout.astro -->
<html>
  <body>
    <nav>Nav</nav>
    <slot /> <!-- BlogLayout goes here -->
    <footer>Footer</footer>
  </body>
</html>

<!-- BlogLayout.astro -->
---
import BaseLayout from './BaseLayout.astro';
---

<BaseLayout>
  <article>
    <div class="blog-meta">Date, Author, etc.</div>
    <slot /> <!-- Blog post content goes here -->
  </article>
</BaseLayout>

<!-- my-blog-post.astro -->
---
import BlogLayout from '../layouts/BlogLayout.astro';
---

<BlogLayout>
  <h1>My Post</h1>
  <p>Content here</p>
</BlogLayout>

💡 This creates layers: BaseLayout wraps BlogLayout wraps your content!

✨ Layout Best Practices

✅ DO: Keep layouts simple

Layouts should handle structure, not complex logic

✅ DO: Use descriptive names

BaseLayout, BlogLayout, ProjectLayout (clear purpose)

✅ DO: Put layouts in src/layouts/

Standard convention, easy to find

✅ DO: Accept props for flexibility

Let pages customize titles, descriptions, etc.

❌ DON'T: Put page-specific content in layouts

Layouts should work for multiple pages

❌ DON'T: Over-nest layouts

2-3 levels max, or it gets confusing

🤔 Layouts vs Components - What's the Difference?

Feature Layout Component
Purpose Wrap entire pages Reusable UI pieces
Uses <slot /> Yes (usually) Sometimes
Location src/layouts/ src/components/
Contains <html> Usually yes Usually no
Examples Page structure, nav, footer Button, Card, Modal
Used per page One per page Multiple per page

Simple rule:

Layout = Page wrapper (structure)
Component = Reusable UI element (content)

🌍 Real-World Example: Portfolio Site

Your portfolio site structure:

src/
├── layouts/
│   ├── BaseLayout.astro       (HTML, nav, footer)
│   └── ProjectLayout.astro    (For project pages)
├── components/
│   ├── Nav.astro              (Navigation bar)
│   ├── Footer.astro           (Footer)
│   └── ProjectCard.astro      (Project preview card)
└── pages/
    ├── index.astro            (Uses BaseLayout)
    ├── about.astro            (Uses BaseLayout)
    └── projects/
        ├── project-1.astro    (Uses ProjectLayout)
        └── project-2.astro    (Uses ProjectLayout)

Workflow benefits:

🚀 What's Next?