What Causes This Error?
This error occurs when you use a slot name that is reserved by Astro or conflicts with internal naming conventions. Certain slot names are reserved for Astro’s internal use.
The Problem
---
// Component.astro
---
<!-- ❌ Using reserved slot name -->
<slot name="default" />
---
// Usage
import Component from './Component.astro';
---
<Component>
<span slot="default">Content</span>
</Component>
The Fix
Use Different Slot Name
---
// Component.astro
---
<!-- ✅ Use non-reserved name -->
<slot name="content" />
<slot name="main" />
Use Unnamed Default Slot
---
// Component.astro
---
<!-- ✅ Unnamed slot is the default -->
<slot />
---
// Usage - content goes to default slot automatically
import Component from './Component.astro';
---
<Component>
<p>This goes to default slot</p>
</Component>
Common Scenarios
Named Slots Pattern
---
// Card.astro
---
<div class="card">
<header class="card-header">
<slot name="header" />
</header>
<main class="card-body">
<slot /> <!-- Default slot -->
</main>
<footer class="card-footer">
<slot name="footer" />
</footer>
</div>
---
// Usage
import Card from './Card.astro';
---
<Card>
<h2 slot="header">Card Title</h2>
<p>Main content goes here (default slot)</p>
<button slot="footer">Action</button>
</Card>
Multiple Named Slots
---
// Layout.astro
---
<html>
<head>
<slot name="head" />
</head>
<body>
<nav>
<slot name="nav" />
</nav>
<main>
<slot />
</main>
<aside>
<slot name="sidebar" />
</aside>
</body>
</html>
Slot Fallback Content
---
// Button.astro
---
<button>
<slot name="icon">
<!-- Fallback if no icon provided -->
<span>→</span>
</slot>
<slot>
<!-- Fallback text -->
Click me
</slot>
</button>
Valid Slot Names
<!-- ✅ Good slot names -->
<slot name="header" />
<slot name="footer" />
<slot name="sidebar" />
<slot name="content" />
<slot name="title" />
<slot name="actions" />
<slot name="icon" />
<slot name="before" />
<slot name="after" />
<!-- Use unnamed for default -->
<slot />
Checking for Slot Content
---
// Astro provides Astro.slots to check slot content
const hasHeader = Astro.slots.has('header');
const hasFooter = Astro.slots.has('footer');
---
<div class="card">
{hasHeader && (
<header>
<slot name="header" />
</header>
)}
<main>
<slot />
</main>
{hasFooter && (
<footer>
<slot name="footer" />
</footer>
)}
</div>
Rendering Slots Programmatically
---
const headerContent = await Astro.slots.render('header');
const hasHeader = headerContent.trim().length > 0;
---
{hasHeader && <header set:html={headerContent} />}
Quick Checklist
- Don’t use
name="default"- use unnamed<slot />instead - Use descriptive slot names:
header,footer,sidebar - Check
Astro.slots.has('name')for conditional rendering - Provide fallback content inside
<slot>tags - Unnamed slot receives all non-slotted children