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 →