> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/withastro/astro/llms.txt
> Use this file to discover all available pages before exploring further.

# Layouts

> Learn how to create and use layout components to share common page structures in Astro

Layouts are special Astro components used to provide a reusable structure for your pages. They typically include common elements like headers, footers, navigation, and meta tags.

## What are Layouts?

A layout is just an Astro component that wraps page content using the `<slot />` element. There's nothing special about a layout file—it's a regular `.astro` component.

```astro title="src/layouts/BaseLayout.astro" theme={null}
---
const { title } = Astro.props;
---

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>{title}</title>
  </head>
  <body>
    <header>
      <nav>
        <a href="/">Home</a>
        <a href="/about">About</a>
        <a href="/blog">Blog</a>
      </nav>
    </header>
    
    <main>
      <slot />
    </main>
    
    <footer>
      <p>&copy; 2024 My Site</p>
    </footer>
  </body>
</html>
```

## Using a Layout

Import and use layouts like any other component:

```astro title="src/pages/index.astro" theme={null}
---
import BaseLayout from '../layouts/BaseLayout.astro';
---

<BaseLayout title="Home Page">
  <h1>Welcome to my site!</h1>
  <p>This content appears in the slot.</p>
</BaseLayout>
```

<Info>
  The content between the opening and closing `<BaseLayout>` tags is passed to the `<slot />` in the layout.
</Info>

## Props to Layouts

Pass data to layouts via props:

```astro title="src/layouts/BlogLayout.astro" theme={null}
---
interface Props {
  title: string;
  description: string;
  author: string;
  pubDate: Date;
}

const { title, description, author, pubDate } = Astro.props;
const formattedDate = pubDate.toLocaleDateString();
---

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="description" content={description} />
    <title>{title}</title>
  </head>
  <body>
    <article>
      <header>
        <h1>{title}</h1>
        <p>By {author} on {formattedDate}</p>
      </header>
      
      <slot />
    </article>
  </body>
</html>
```

Use it:

```astro title="src/pages/blog/my-post.astro" theme={null}
---
import BlogLayout from '../../layouts/BlogLayout.astro';
---

<BlogLayout
  title="My First Post"
  description="This is my first blog post"
  author="Alice"
  pubDate={new Date('2024-01-01')}
>
  <p>This is the blog post content.</p>
  <p>It can contain multiple paragraphs.</p>
</BlogLayout>
```

## Nesting Layouts

Layouts can import and use other layouts, creating a hierarchy:

```astro title="src/layouts/BaseLayout.astro" theme={null}
---
const { title } = Astro.props;
---

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>{title}</title>
    <link rel="stylesheet" href="/styles/global.css" />
  </head>
  <body>
    <slot />
  </body>
</html>
```

```astro title="src/layouts/BlogLayout.astro" theme={null}
---
import BaseLayout from './BaseLayout.astro';

interface Props {
  title: string;
  author: string;
}

const { title, author } = Astro.props;
---

<BaseLayout title={title}>
  <div class="blog-container">
    <header>
      <h1>{title}</h1>
      <p>By {author}</p>
    </header>
    
    <article>
      <slot />
    </article>
  </div>
</BaseLayout>
```

Now your blog posts automatically get both the blog-specific structure AND the base HTML structure:

```astro title="src/pages/blog/post.astro" theme={null}
---
import BlogLayout from '../../layouts/BlogLayout.astro';
---

<BlogLayout title="My Post" author="Alice">
  <p>Post content here.</p>
</BlogLayout>
```

<Tabs>
  <Tab title="Rendered Structure">
    ```html theme={null}
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <title>My Post</title>
        <link rel="stylesheet" href="/styles/global.css" />
      </head>
      <body>
        <div class="blog-container">
          <header>
            <h1>My Post</h1>
            <p>By Alice</p>
          </header>
          <article>
            <p>Post content here.</p>
          </article>
        </div>
      </body>
    </html>
    ```
  </Tab>
</Tabs>

## Layout with Multiple Slots

Use named slots for more complex layouts:

```astro title="src/layouts/DocumentLayout.astro" theme={null}
---
const { title } = Astro.props;
---

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>{title}</title>
    <slot name="head" />
  </head>
  <body>
    <nav>
      <slot name="nav" />
    </nav>
    
    <main>
      <slot />
    </main>
    
    <aside>
      <slot name="sidebar" />
    </aside>
    
    <footer>
      <slot name="footer">
        <p>Default footer content</p>
      </slot>
    </footer>
  </body>
</html>
```

Use named slots:

```astro title="src/pages/docs.astro" theme={null}
---
import DocumentLayout from '../layouts/DocumentLayout.astro';
---

<DocumentLayout title="Documentation">
  <link slot="head" rel="stylesheet" href="/docs.css" />
  
  <nav slot="nav">
    <a href="/docs">Docs</a>
    <a href="/api">API</a>
  </nav>
  
  <h1>Documentation</h1>
  <p>Main content goes in the default slot.</p>
  
  <div slot="sidebar">
    <h3>Table of Contents</h3>
    <ul>
      <li><a href="#intro">Introduction</a></li>
      <li><a href="#guide">Guide</a></li>
    </ul>
  </div>
  
  <p slot="footer">Custom footer for this page</p>
</DocumentLayout>
```

## Markdown Layouts

Markdown and MDX files can specify a layout in their frontmatter:

```markdown title="src/pages/blog/post.md" theme={null}
---
layout: ../../layouts/BlogLayout.astro
title: My Blog Post
author: Alice
---

# My Blog Post

This is the markdown content.
```

The layout receives frontmatter data as props:

```astro title="src/layouts/BlogLayout.astro" theme={null}
---
const { frontmatter } = Astro.props;
const { title, author } = frontmatter;
---

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>{title}</title>
  </head>
  <body>
    <article>
      <h1>{title}</h1>
      <p>By {author}</p>
      <slot />
    </article>
  </body>
</html>
```

<Note>
  The `<slot />` contains the rendered markdown content.
</Note>

## Real-World Example

Here's a production-ready layout from the Astro source code examples:

```astro title="src/layouts/BaseLayout.astro" theme={null}
---
interface Props {
  title: string;
  description?: string;
  image?: string;
}

const { 
  title, 
  description = 'Default site description',
  image = '/default-og-image.jpg'
} = Astro.props;

const canonicalURL = new URL(Astro.url.pathname, Astro.site);
---

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="canonical" href={canonicalURL} />
    
    <!-- Primary Meta Tags -->
    <title>{title}</title>
    <meta name="title" content={title} />
    <meta name="description" content={description} />
    
    <!-- Open Graph / Facebook -->
    <meta property="og:type" content="website" />
    <meta property="og:url" content={Astro.url} />
    <meta property="og:title" content={title} />
    <meta property="og:description" content={description} />
    <meta property="og:image" content={new URL(image, Astro.url)} />
    
    <!-- Twitter -->
    <meta property="twitter:card" content="summary_large_image" />
    <meta property="twitter:url" content={Astro.url} />
    <meta property="twitter:title" content={title} />
    <meta property="twitter:description" content={description} />
    <meta property="twitter:image" content={new URL(image, Astro.url)} />
    
    <slot name="head" />
  </head>
  <body>
    <header>
      <nav>
        <a href="/">Home</a>
        <a href="/about">About</a>
        <a href="/blog">Blog</a>
      </nav>
    </header>
    
    <main>
      <slot />
    </main>
    
    <footer>
      <p>&copy; {new Date().getFullYear()} My Site</p>
    </footer>
  </body>
</html>
```

## Layout Patterns

<Tabs>
  <Tab title="Base Layout">
    ```astro theme={null}
    ---
    // Minimal HTML structure
    const { title } = Astro.props;
    ---
    <!DOCTYPE html>
    <html>
      <head>
        <title>{title}</title>
      </head>
      <body>
        <slot />
      </body>
    </html>
    ```
  </Tab>

  <Tab title="App Layout">
    ```astro theme={null}
    ---
    // Adds nav and footer
    import BaseLayout from './BaseLayout.astro';
    ---
    <BaseLayout>
      <nav><slot name="nav" /></nav>
      <main><slot /></main>
      <footer><slot name="footer" /></footer>
    </BaseLayout>
    ```
  </Tab>

  <Tab title="Content Layout">
    ```astro theme={null}
    ---
    // Adds article structure
    import AppLayout from './AppLayout.astro';
    const { frontmatter } = Astro.props;
    ---
    <AppLayout>
      <article>
        <h1>{frontmatter.title}</h1>
        <slot />
      </article>
    </AppLayout>
    ```
  </Tab>
</Tabs>

## Dynamic Layouts

Conditionally render different layouts:

```astro title="src/layouts/ConditionalLayout.astro" theme={null}
---
import LightLayout from './LightLayout.astro';
import DarkLayout from './DarkLayout.astro';

const { theme = 'light', title } = Astro.props;
const Layout = theme === 'dark' ? DarkLayout : LightLayout;
---

<Layout title={title}>
  <slot />
</Layout>
```

## Best Practices

<Steps>
  <Step title="Start with a base layout">
    Create a minimal base layout with essential HTML structure.
  </Step>

  <Step title="Create specialized layouts">
    Build specialized layouts that extend the base for different page types.
  </Step>

  <Step title="Use TypeScript">
    Type your layout props for better developer experience.
  </Step>

  <Step title="Keep layouts focused">
    Each layout should serve a specific purpose (blog, docs, landing page).
  </Step>

  <Step title="Use slots wisely">
    Named slots provide flexibility, but don't overuse them.
  </Step>
</Steps>

<CardGroup cols={2}>
  <Card title="Prefer composition" icon="puzzle">
    Nest layouts instead of duplicating code.
  </Card>

  <Card title="Default props" icon="settings">
    Provide sensible defaults for optional props.
  </Card>

  <Card title="SEO metadata" icon="search">
    Include SEO tags in your base layout.
  </Card>

  <Card title="Consistent structure" icon="layers">
    Keep similar pages using the same layout.
  </Card>
</CardGroup>

## Learn More

<CardGroup cols={2}>
  <Card title="Components" href="/concepts/components">
    Learn about Astro component basics
  </Card>

  <Card title="Content Collections" href="/concepts/content-collections">
    Type-safe content with automatic layouts
  </Card>
</CardGroup>
