Astro mit Claude Code: Content-Sites und Static Generation 2026
Astro ist das Framework der Wahl für Content-fokussierte Sites — Zero JS by default, Islands Architecture, Content Collections, MDX-Support. Claude Code kennt alle Astro-Patterns: von einfachen Landing Pages bis zu komplexen Blogs mit Suche und Filtering.
Warum Astro? Islands Architecture erklärt
IslandsZero JS by default — nur was nötig ist
# Astro's Kern-Philosophie: Ship zero JS by default
# Nur interaktive Inseln werden hydriert
// src/pages/index.astro — Statische Seite
---
import Hero from '../components/Hero.astro'
import Features from '../components/Features.astro'
import SearchBar from '../components/SearchBar.tsx' // React-Komponente!
const posts = await getCollection('blog')
---
<html lang="de">
<head><title>Blog</title></head>
<body>
<Hero /> <!-- Statisch — kein JS -->
<Features /> <!-- Statisch — kein JS -->
<SearchBar client:load /> <!-- Island: React lädt sofort -->
<!-- client:idle = nach Main-Thread idle -->
<!-- client:visible = wenn im Viewport -->
<!-- client:only = nur client, kein SSR -->
</body>
</html>
# Lighthouse Score: 100/100 Performance
# → Blog-Post-Seite: 0 KB JavaScript gesendet
Astro vs Next.js Decision: Content-Site (Blog, Docs, Marketing) → Astro. Interaktive App (Dashboard, SaaS) → Next.js. Claude Code kennt beide und empfiehlt je nach Anwendungsfall.
Content Collections: Typsichere Inhalte
CollectionsMDX mit Zod-Schema typisieren
# Prompt: "Content Collection für Blog-Posts mit Kategorien und SEO-Feldern"
// src/content/config.ts
import { defineCollection, z } from 'astro:content'
const blogCollection = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string().max(160),
pubDate: z.date(),
author: z.string(),
category: z.enum(['tutorial', 'guide', 'news']),
tags: z.array(z.string()),
image: z.object({ src: z.string(), alt: z.string() }).optional(),
draft: z.boolean().default(false)
})
})
export const collections = { blog: blogCollection }
// src/pages/blog/[slug].astro
---
import { getCollection, getEntry } from 'astro:content'
export async function getStaticPaths() {
const posts = await getCollection('blog', ({ data }) => !data.draft)
return posts.map(post => ({ params: { slug: post.slug } }))
}
const { slug } = Astro.params
const post = await getEntry('blog', slug!)
const { Content } = await post.render()
---
<article>
<h1>{post.data.title}</h1>
<Content /> <!-- MDX gerendert -->
</article>
Astro Komponenten: .astro, React, Vue
SyntaxAstro-Komponenten-Syntax
# Prompt: "Astro BlogCard-Komponente mit Props-Interface und Styling"
// src/components/BlogCard.astro
---
interface Props {
title: string
description: string
pubDate: Date
slug: string
category: string
tags: string[]
}
const { title, description, pubDate, slug, category, tags } = Astro.props
const formattedDate = new Intl.DateTimeFormat('de-DE', {
year: 'numeric', month: 'long', day: 'numeric'
}).format(pubDate)
---
<article class="blog-card">
<span class="category">{category}</span>
<h2><a href={`/blog/${slug}`}>{title}</a></h2>
<p>{description}</p>
<time datetime={pubDate.toISOString()}>{formattedDate}</time>
<div class="tags">
{tags.map(tag => <span class="tag">{tag}</span>)}
</div>
</article>
<style>
.blog-card { border-radius: 8px; padding: 24px; }
.category { font-size: .8rem; font-weight: 700; }
/* Styles sind automatisch scoped! */
</style>
SSR-Modus und API-Endpoints
# Prompt: "Astro SSR-Modus aktivieren, API-Endpoint für Kontaktformular"
// astro.config.mjs
export default defineConfig({
output: 'hybrid', // SSG by default, opt-in SSR
adapter: vercel(), // oder netlify(), node()
integrations: [
react(), // React Islands
tailwind(),
sitemap(),
mdx()
]
})
// src/pages/api/contact.ts — API-Endpoint
import type { APIRoute } from 'astro'
export const POST: APIRoute = async ({ request }) => {
const data = await request.json()
const { name, email, message } = contactSchema.parse(data)
await sendEmail({ name, email, message })
return new Response(
JSON.stringify({ success: true }),
{ status: 200, headers: { 'Content-Type': 'application/json' } }
)
}
// Dynamische SSR-Seite (opt-out SSG)
// export const prerender = false
// → Diese Seite wird bei jedem Request gerendert
PerformanceView Transitions und Image-Optimierung
# Prompt: "View Transitions für Blog-Navigation, optimierte Bilder"
// Astro View Transitions (SPA-feeling ohne SPA)
import { ViewTransitions } from 'astro:transitions'
// In BaseLayout.astro head:
<ViewTransitions />
// → Smooth page transitions zwischen Routen
// → transition:animate="slide" an Elementen
// Astro Image-Optimierung (automatisch)
import { Image } from 'astro:assets'
import heroImage from '../assets/hero.jpg'
<Image
src={heroImage}
alt="Hero"
width={1200}
height={600}
format="webp"
quality={85}
/>
// → Automatisch WebP, AVIF, srcset, lazy loading
# Astro vs Next.js für Content-Sites:
# Astro: Blog, Docs, Marketing — Performance-First
# Next.js: SaaS, Dashboards — Interaktions-First
# Astro kann React/Vue/Svelte Islands — Beste aus beiden Welten
Astro Häufiger Fehler: React-Komponenten ohne
client:*-Direktive sind statisch — kein useState, kein useEffect möglich. Claude Code erkennt diesen Fehler und fügt automatisch die richtige client-Direktive ein.Astro-Modul im Kurs
Im Claude Code Mastery Kurs: vollständiges Astro-Modul mit Content Collections, Islands Architecture, MDX, SSG/SSR-Hybrid und Performance-Optimierung — für blitzschnelle Content-Sites.
14 Tage kostenlos testen →