Welcome back to the Learning Astro series! In this second part, we’ll explore Astro components in depth.
Anatomy of an Astro Component
Every Astro component has two parts:
- Component Script (frontmatter) — JavaScript that runs at build time
- Component Template — HTML output of your component
---
// Component Script (runs at build time)
const greeting = "Hello, World!";
const items = ["Apple", "Banana", "Cherry"];
---
<!-- Component Template -->
<div>
<h1>{greeting}</h1>
<ul>
{items.map(item => <li>{item}</li>)}
</ul>
</div>
Props: Passing Data to Components
Components can accept props just like React or Vue:
---
// src/components/Button.astro
interface Props {
variant?: "primary" | "secondary";
size?: "sm" | "md" | "lg";
}
const { variant = "primary", size = "md" } = Astro.props;
---
<button class:list={["btn", `btn-${variant}`, `btn-${size}`]}>
<slot />
</button>
Use the component:
<Button variant="primary" size="lg">
Click Me
</Button>
Slots: Component Composition
Slots let you pass children to components:
Default Slot
---
// Card.astro
---
<div class="card">
<slot />
</div>
Named Slots
---
// Card.astro
---
<div class="card">
<header>
<slot name="header" />
</header>
<main>
<slot />
</main>
<footer>
<slot name="footer" />
</footer>
</div>
Usage:
<Card>
<h2 slot="header">Card Title</h2>
<p>Main content goes here.</p>
<button slot="footer">Learn More</button>
</Card>
Conditional Rendering
Astro supports standard JavaScript conditionals:
---
const isLoggedIn = true;
const items = [];
---
{isLoggedIn && <p>Welcome back!</p>}
{items.length > 0 ? (
<ul>
{items.map(item => <li>{item}</li>)}
</ul>
) : (
<p>No items found.</p>
)}
Styling Components
Scoped Styles
Styles in Astro are scoped by default:
<style>
/* Only applies to this component */
.card {
padding: 1rem;
border-radius: 8px;
}
</style>
Global Styles
Use is:global for global styles:
<style is:global>
body {
font-family: system-ui;
}
</style>
What’s Next?
In the final post, we’ll explore Content Collections - Astro’s powerful system for managing blog posts and other content.
Pro tip: Keep components small and focused. A good rule of thumb is that each component should do one thing well.