Slots
React passes children via the children prop. Astro uses <slot /> — a Web Component concept built right into the template. The result is the same: the parent decides what goes inside, the component decides where it goes.
Default slot (children equivalent)
Section titled “Default slot (children equivalent)”// Card.jsxexport default function Card({ children }) { return ( <div className="card"> {children} </div> );}
// Usage:// <Card>// <h2>Title</h2>// <p>Body text</p>// </Card>---// Card.astro---<div class="card"> <slot /></div>
<!-- Usage:<Card> <h2>Title</h2> <p>Body text</p></Card>-->No prop declaration needed — <slot /> automatically receives any children passed to the component. If no children are passed, the slot renders nothing (you can provide fallback content between the slot tags: <slot>Default content</slot>).
Named slots
Section titled “Named slots”React doesn’t have native named slots. Common patterns are render props, compound components, or separate props like header={<H1 />}. Astro has first-class named slots.
In the component definition, place <slot name="header" /> where you want header content to appear.
In the component usage, add slot="header" to any child element to route it to that slot.
// Layout.jsx — React named-slot workaroundexport default function Layout({ header, sidebar, children }) { return ( <div className="layout"> <header>{header}</header> <aside>{sidebar}</aside> <main>{children}</main> </div> );}
// Usage:// <Layout// header={<nav>Nav here</nav>}// sidebar={<ul>Links</ul>}// >// <p>Main content</p>// </Layout>---// Layout.astro---<div class="layout"> <header><slot name="header" /></header> <aside><slot name="sidebar" /></aside> <main><slot /></main></div>
<!-- Usage:<Layout> <nav slot="header">Nav here</nav> <ul slot="sidebar">Links</ul> <p>Main content</p></Layout>-->Runnable example
Section titled “Runnable example”---
// No frontmatter needed for this demo
---
<html lang="en">
<head><meta charset="utf-8" /><title>Slots demo</title></head>
<body style="font-family:sans-serif;padding:2rem;max-width:600px;margin:auto">
<style>
.card { border:1px solid #e2e8f0; border-radius:8px; overflow:hidden; }
.card header { background:#6366f1; color:#fff; padding:1rem; }
.card main { padding:1rem; }
.card footer { background:#f8fafc; padding:.75rem 1rem; font-size:.875rem; color:#64748b; }
</style>
<!-- Inline component demo using an HTML template pattern -->
<div class="card">
<header>
<h2>Named Slots</h2>
</header>
<main>
<p>The default slot receives children with no slot attribute.</p>
<p>Named slots receive children tagged with slot="name".</p>
</main>
<footer>No JavaScript required.</footer>
</div>
</body>
</html>