Astro Components

6 Kernkonzepte
Die wichtigsten Konzepte für Astro-Komponenten: .astro · Frontmatter · Props · Slots · Scripts & Styles · Frameworks Astro-Komponenten sind das Herzstück jeder Astro-Anwendung. Sie kombinieren serverseitigen Code, HTML-Templates und komponentenspezifische Styles in einer einzigen Datei.

.astro Grundlagen – Frontmatter & Template

--- · Astro.props · HTML
--- // Frontmatter – serverseitiger Code const title = "Hello World"; const items = ["eins", "zwei", "drei"]; --- <html> <h1>{ title }</h1> <ul> {items.map(item => <li>{item}</li>)} </ul> </html>

.astro-Dateien bestehen aus einem Frontmatter (Code-Block) und einem HTML-Template. Der Frontmatter-Code wird serverseitig ausgeführt und nie an den Client gesendet.

Beispiele
---
// Importe
import Button from '../components/Button.astro';
import { getCollection } from 'astro:content';
// Asynchrone Daten laden (nur serverseitig)
const posts = await getCollection('blog');
// Helper-Funktionen
function formatDate(date) {
return new Date(date).toLocaleDateString('de-DE');
}
---
<h1>Blog</h1>
{posts.map(post => (
<article>
<h2><a href={`/blog/${post.slug}`}>{post.data.title}</a></h2>
<p>{formatDate(post.data.pubDate)}</p>
<p>{post.data.description}</p>
</article>
))}
Tipp: Der Frontmatter-Code wird nur auf dem Server ausgeführt. Das macht Astro-Komponenten extrem sicher – keine sensiblen Daten gelangen zum Client.

Props – Daten an Komponenten übergeben

Astro.props · export interface Props
--- export interface Props { title: string; description?: string; } const { title, description } = Astro.props; --- <h1>{title}</h1> {description && <p>{description}</p>}

Props werden über Astro.props in der Komponente empfangen. Typdefinitionen mit TypeScript sorgen für Typsicherheit.

Beispiele
<!-- Card.astro -->
---
export interface Props {
title: string;
image?: { src: string; alt: string; };
url: string;
variant: 'primary' | 'secondary';
}
const { title, image, url, variant } = Astro.props;
const classes = `card-${variant}`;
---
<div class={ classes }>
{ image && <img src={image.src} alt={image.alt} /> }
<h3>{ title }</h3>
<a href={ url } class="btn">Mehr</a>
</div>
<style>
.card-primary { background: #ff5d01; }
.card-secondary { background: #f0f0f0; }
</style>
<!-- Verwendung -->
<Card
title="Mein Blogpost"
image={{ src: "/bild.jpg", alt: "Bild" }}
url="/blog/mein-post"
variant="primary"
/>
Tipp: Nutzen Sie TypeScript-Interfaces für Ihre Props, um Typsicherheit und automatische Vervollständigung im Editor zu erhalten.

Slots – Flexible Inhaltsbereiche

<slot /> · <slot name="..." />
// Layout-Komponente <div class="layout"> <header><slot name="header">Default Header</slot></header> <main><slot /></main> <footer><slot name="footer">Default Footer</slot></footer> </div>

Slots ermöglichen es, Inhalte von der übergeordneten Komponente in die untergeordnete Komponente zu übergeben. Benannte Slots erlauben mehrere Inhaltsbereiche.

Beispiele
<!-- Layout.astro -->
---
export interface Props {
title: string;
}
const { title } = Astro.props;
---
<html lang="de">
<head>
<title>{ title }</title>
<slot name="head" />
</head>
<body>
<nav><slot name="nav">Default Nav</slot></nav>
<main><slot /></main>
<footer><slot name="footer">© 2025</slot></footer>
</body>
</html>
<!-- Verwendung -->
<Layout title="Startseite">
<slot name="nav">
<a href="/">Home</a>
<a href="/blog">Blog</a>
</slot>
<h1>Willkommen auf meiner Seite</h1>
<p>Hauptinhalt der Seite.</p>
<slot name="footer">
© 2025 Meine Website
</slot>
</Layout>
Tipp: Der Standard-Slot (<slot />) wird verwendet, wenn kein benannter Slot angegeben ist. Benannte Slots erlauben mehrere Inhaltsbereiche in einer Komponente.

Scripts & Styles – Client-seitige Logik & CSS

<script> · <style> · define:vars
// Frontmatter const primaryColor = "#ff5d01"; const isDarkMode = false; <script> // Client-seitiges JavaScript console.log("Hallo Welt"); </script> <style define:vars={{ primaryColor, isDarkMode }}> .primary { color: var(--primaryColor); } </style>

Scripts und Styles in Astro-Komponenten werden standardmäßig serverseitig verarbeitet. Mit <script> können Sie client-seitiges JavaScript hinzufügen, mit define:vars CSS-Variablen aus dem Frontmatter übergeben.

Beispiele
---
const theme = "dark";
---
<!-- Client-seitiges Script (isoliert) -->
<script>
// Dieses Script wird automatisch gebündelt und nur ausgeführt,
// wenn die Komponente gerendert wird
document.querySelector('button').addEventListener('click', () => {
console.log('Button geklickt!');
});
</script>
<!-- Globales Script (seitenweit) -->
<script is:global>
// Dieses Script wird global verfügbar sein
</script>
<!-- Styles mit CSS-Variablen aus Frontmatter -->
<style define:vars={{ { theme } }}>
body { background: var(--theme); }
.component {
border: 1px solid var(--theme);
}
</style>
<!-- Komponenten-Scoped Styles (automatisch) -->
<style>
/* Diese Styles gelten nur für diese Komponente */
h1 { color: #ff5d01; }
.btn { padding: 0.5rem 1rem; }
</style>
Tipp: Verwenden Sie define:vars für dynamische Styles, die von Frontmatter-Variablen abhängen. Das erzeugt automatisch CSS-Custom-Properties, die im Template verwendet werden können.

Framework-Komponenten – React, Vue, Svelte in Astro

.jsx · .vue · .svelte · client:*
// astro.config.mjs import react from '@astrojs/react'; import vue from '@astrojs/vue'; import svelte from '@astrojs/svelte'; export default defineConfig({ integrations: [react(), vue(), svelte()] }); // In .astro-Datei import Counter from '../components/Counter.jsx'; import VueComponent from '../components/VueComponent.vue'; <Counter client:load />

Framework-Komponenten ermöglichen die Nutzung von React, Vue, Svelte und anderen Frameworks in Astro. Die entsprechende Integration muss zuerst installiert werden.

Beispiele
<!-- React-Komponente importieren und nutzen -->
---
import ReactCounter from '../components/ReactCounter.jsx';
import VueButton from '../components/VueButton.vue';
import SvelteToggle from '../components/SvelteToggle.svelte';
---
<!-- React: wird sofort hydriert -->
<ReactCounter client:load initialCount={10} />
<!-- Vue: wird geladen, wenn Browser idle ist -->
<VueButton client:idle label="Klick mich" />
<!-- Svelte: wird nur geladen, wenn sichtbar -->
<SvelteToggle client:visible defaultChecked={ true } />
<!-- Props-Übergabe (Framework-unabhängig) -->
<ReactCounter client:load initialCount={ 42 } title="Mein Counter" />
<!-- Slot-Übergabe an Framework-Komponente -->
<VueButton client:load>
<span>Benutzerdefinierter Inhalt</span>
</VueButton>
<!-- Nested Frameworks (React in Vue) wird unterstützt -->
Tipp: Framework-Komponenten werden standardmäßig zu statischem HTML gerendert und erhalten erst durch die client:*-Direktiven interaktives JavaScript. Das reduziert die Bundle-Größe erheblich.

Astro Components im Überblick

.astro Komponentendatei
Frontmatter + HTML + CSS
Astro.props Props empfangen
export interface Props
<slot /> Inhaltsbereiche
Benannte Slots möglich
<script> Client-seitiges JS
is:global, define:vars
<style> Scoped CSS
define:vars für Dynamik
client:* Hydration-Direktiven
load, idle, visible

Quick Summary

.astro
Komponente
Astro.props
Props
<slot />
Slots
<script>
Client-JS
<style>
Styles
client:load
Frameworks
const { title } = Astro.props; · <slot name="header" /> · <Counter client:load />