Static Site & Performance

Astro mit Claude Code: Blitzschnelle Websites 2026

Astro: Islands Architecture, Content Collections, View Transitions, MDX, React/Vue/Svelte-Integration — Claude Code baut Zero-JS-Websites mit maximaler Performance.

6. Mai 2026 10 min Lesezeit Von SpockyMagicAI

Astro ist 2026 das bevorzugte Framework für Content-lastige Websites, Blogs, Dokumentationen und Marketing-Pages. Das Killer-Feature: standardmäßig wird kein JavaScript an den Browser geliefert — nur dann, wenn es wirklich nötig ist. Mit Claude Code lassen sich Astro-Projekte blitzschnell aufsetzen, Content Collections typsicher verwalten und React-, Vue- oder Svelte-Komponenten gezielt als interaktive Islands einbinden.

Was du in diesem Guide lernst

1. Astro Grundlagen: .astro-Dateiformat & Zero-JS-Default

Astro-Komponenten haben die Dateiendung .astro und bestehen aus zwei Teilen: dem Component Script (Frontmatter zwischen ----Trennern) und dem Component Template (HTML-ähnliche Syntax darunter). Der entscheidende Unterschied zu React oder Vue: Das Script läuft ausschließlich zur Build-Zeit auf dem Server — kein JavaScript landet standardmäßig im Browser.

Minimales .astro-File

// src/pages/index.astro --- // Component Script — läuft NUR zur Build-Zeit (Node.js) const title = 'Meine Astro-Website'; const posts = await fetch('https://api.example.com/posts').then(r => r.json()); --- <!-- Component Template — JSX-ähnliche Syntax --> <html lang="de"> <head> <title>{title}</title> </head> <body> <h1>{title}</h1> <ul> {posts.map(post => ( <li><a href={`/posts/${post.slug}`}>{post.title}</a></li> ))} </ul> </body> </html>

Astro.props & Komponenten-Komposition

Wiederverwendbare Astro-Komponenten empfangen Daten über Astro.props. TypeScript-Interfaces machen Props vollständig typsicher.

// src/components/BlogCard.astro --- interface Props { title: string; excerpt: string; slug: string; publishedAt: Date; readTime?: number; } const { title, excerpt, slug, publishedAt, readTime = 5 } = Astro.props; const formattedDate = new Intl.DateTimeFormat('de-DE', { day: 'numeric', month: 'long', year: 'numeric' }).format(publishedAt); --- <article class="blog-card"> <h2><a href={`/blog/${slug}`}>{title}</a></h2> <p>{excerpt}</p> <footer> <time datetime={publishedAt.toISOString()}>{formattedDate}</time> <span>{readTime} min Lesezeit</span> </footer> </article> <style> /* Scoped CSS — automatisch nur für diese Komponente */ .blog-card { border: 1px solid #e2e8f0; border-radius: 8px; padding: 1.5rem; } .blog-card h2 a { text-decoration: none; color: inherit; } </style>

Build-Output: statisches HTML

# Astro-Projekt erstellen + bauen npm create astro@latest my-site -- --template minimal --typescript strict cd my-site npm run build # dist/ enthält reines, optimiertes HTML — kein JavaScript-Bundle # Lighthouse Score: ~100 Performance out of the box dist/ index.html # 2.1 KB (kein JS!) blog/ mein-post/ index.html # Jede Route = statische HTML-Datei

Zero-JS by Default — Warum das wichtig ist

2. Islands Architecture: Selektive Hydration

Islands client:load client:idle client:visible

Das Herzstück von Astro ist die Islands Architecture: Die Seite ist statisches HTML, aber einzelne "Inseln" können interaktive Framework-Komponenten (React, Vue, Svelte, Solid, Preact) sein — mit präziser Kontrolle darüber, wann die Hydration stattfindet.

Hydration-Direktiven im Überblick

Direktive Wann hydriert? Use Case
client:loadSofort beim SeitenloadHero-Navigation, kritische Widgets
client:idleWenn Browser idle (requestIdleCallback)Footer-Chat, sekundäre Features
client:visibleWenn in Viewport sichtbar (IntersectionObserver)Tief im Scroll liegende Widgets
client:mediaWenn CSS Media Query matchtMobile-only Slider
client:onlyNur im Browser, kein SSRChart.js, Maps, Browser-APIs

React-Komponente als Island einbinden

// src/components/SearchWidget.tsx — Normale React-Komponente import { useState, useCallback } from 'react'; interface SearchWidgetProps { placeholder?: string; onSearch: (query: string) => void; } export default function SearchWidget({ placeholder = 'Suchen...', onSearch }: SearchWidgetProps) { const [query, setQuery] = useState(''); const handleSubmit = useCallback((e: React.FormEvent) => { e.preventDefault(); onSearch(query); }, [query, onSearch]); return ( <form onSubmit={handleSubmit} className="search-form"> <input type="search" value={query} onChange={e => setQuery(e.target.value)} placeholder={placeholder} /> <button type="submit">Suchen</button> </form> ); }
// src/pages/blog/index.astro — Island einbinden --- import SearchWidget from '../../components/SearchWidget'; import BlogCard from '../../components/BlogCard.astro'; --- <main> <h1>Blog</h1> <!-- client:visible = React-JS wird erst geladen wenn Widget sichtbar --> <SearchWidget client:visible placeholder="Artikel suchen..." onSearch={query => console.log(query)} /> <!-- Statische Astro-Komponenten — kein JS --> <div class="grid"> <BlogCard title="Erster Post" slug="erster-post" excerpt="..." publishedAt={new Date()} /> </div> </main>

client:only — Browser-exklusive Komponenten

// Für Komponenten die auf Browser-APIs angewiesen sind (window, document, localStorage) // client:only verhindert SSR-Fehler und lädt nur im Browser --- import MapComponent from '../components/MapComponent'; import ChartDashboard from '../components/ChartDashboard'; --- <!-- "react" teilt Astro mit welches Framework-Runtime geladen werden soll --> <MapComponent client:only="react" center={[52.52, 13.405]} /> <!-- Svelte-Komponente als Island --> <ChartDashboard client:only="svelte" data={analyticsData} />

3. Content Collections: Typsichere Inhalte mit Zod

Collections MDX Zod Schema

Content Collections sind Astros Antwort auf die Frage: "Wie verwalte ich strukturierte Inhalte typsicher?" Mit defineCollection und Zod-Schemas werden alle Markdown/MDX-Frontmatter-Felder zur Build-Zeit validiert — fehlendes Pflichtfeld = Build-Fehler, keine Runtime-Überraschungen.

Collection Schema definieren

// src/content/config.ts — Zentrale Konfiguration aller Collections import { defineCollection, z } from 'astro:content'; const blogCollection = defineCollection({ type: 'content', // 'content' für MD/MDX, 'data' für JSON/YAML schema: z.object({ title: z.string().max(80), description: z.string().max(160), publishedAt: z.coerce.date(), updatedAt: z.coerce.date().optional(), author: z.string().default('SpockyMagicAI'), tags: z.array(z.string()).default([]), draft: z.boolean().default(false), image: z.object({ src: z.string(), alt: z.string(), }).optional(), readTime: z.number().positive().optional(), }), }); const docsCollection = defineCollection({ type: 'content', schema: z.object({ title: z.string(), sidebar: z.object({ order: z.number(), label: z.string().optional() }), category: z.enum(['guide', 'reference', 'tutorial']), }), }); export const collections = { blog: blogCollection, docs: docsCollection, };

Markdown-Frontmatter mit Schema

# src/content/blog/astro-guide.md --- title: "Astro Anfänger-Guide 2026" description: "Alles über Astro: Islands, Collections und Performance" publishedAt: "2026-05-06" author: "Daniel Bratschke" tags: ["astro", "performance", "ssg"] readTime: 8 image: src: "/images/astro-cover.jpg" alt: "Astro Framework Logo auf dunklem Hintergrund" --- Astro ist das schnellste Framework für content-lastige Websites...

getCollection() & getEntry() — Typsichere Abfragen

// src/pages/blog/index.astro --- import { getCollection, getEntry } from 'astro:content'; // Alle Posts laden — drafts in Produktion herausfiltern const allPosts = await getCollection('blog', ({ data }) => { return import.meta.env.PROD ? data.draft !== true : true; }); // Nach Datum sortieren (neueste zuerst) const sortedPosts = allPosts.sort( (a, b) => b.data.publishedAt.getTime() - a.data.publishedAt.getTime() ); // Einen einzelnen Eintrag laden const featuredPost = await getEntry('blog', 'astro-guide'); --- {sortedPosts.map(post => ( <article> <h2><a href={`/blog/${post.slug}`}>{post.data.title}</a></h2> <p>{post.data.description}</p> <time>{post.data.publishedAt.toLocaleDateString('de-DE')}</time> {post.data.tags.map(tag => <span class="tag">{tag}</span>)} </article> ))}

4. Routing & Pages: File-based Routing & SSR

File Routing SSR API Routes

Astro folgt dem File-System-basierten Routing-Prinzip: Jede Datei in src/pages/ wird zur Route. Für dynamische Routen wie Blog-Posts oder Produkt-Seiten generiert getStaticPaths() alle möglichen Slugs zur Build-Zeit.

Dynamische Routen mit getStaticPaths()

// src/pages/blog/[slug].astro --- import { getCollection } from 'astro:content'; import BlogLayout from '../../layouts/BlogLayout.astro'; import { Image } from 'astro:assets'; export async function getStaticPaths() { const posts = await getCollection('blog'); return posts.map(post => ({ params: { slug: post.slug }, props: { post }, })); } const { post } = Astro.props; const { Content, headings, remarkPluginFrontmatter } = await post.render(); --- <BlogLayout title={post.data.title} description={post.data.description}> <header> <h1>{post.data.title}</h1> {post.data.image && ( <Image src={post.data.image.src} alt={post.data.image.alt} width={1200} height={630} format="webp" /> )} </header> <!-- Content rendert den Markdown/MDX-Inhalt --> <Content /> </BlogLayout>

SSR-Modus: Server-seitige Requests

// astro.config.mjs — SSR aktivieren import { defineConfig } from 'astro/config'; import vercel from '@astrojs/vercel/serverless'; export default defineConfig({ output: 'server', // 'static' | 'hybrid' | 'server' adapter: vercel(), }); // 'hybrid' = SSG default, einzelne Pages opt-in SSR: // export const prerender = false; // in der jeweiligen Page

API-Endpoints in Astro

// src/pages/api/subscribe.ts — REST-Endpoint import type { APIRoute } from 'astro'; export const POST: APIRoute = async ({ request }) => { const body = await request.json(); const { email } = body; if (!email || !email.includes('@')) { return new Response(JSON.stringify({ error: 'Ungültige E-Mail' }), { status: 400, headers: { 'Content-Type': 'application/json' }, }); } // Zur Mailchimp/Resend API senden... const result = await addToMailingList(email); return new Response(JSON.stringify({ success: true, id: result.id }), { status: 200, headers: { 'Content-Type': 'application/json' }, }); };

Routing-Muster in Astro

5. Integrationen: React, Vue, Svelte, Tailwind & MDX

React Vue Svelte Tailwind

Astro's Integrations-System macht es trivial, beliebte Frameworks und Tools hinzuzufügen. Der astro add-Befehl konfiguriert alles automatisch — inklusive TypeScript-Definitionen.

Integrationen installieren

# Framework-Integrationen (können kombiniert werden!) npx astro add react # React 18 + JSX-Transform npx astro add vue # Vue 3 Composition API npx astro add svelte # Svelte 5 (Runes-Syntax) npx astro add preact # Preact — minimales React-kompatibles Framework npx astro add solid-js # Solid.js — reaktiv, kein VDOM # CSS & Styling npx astro add tailwind # Tailwind CSS v4 + PostCSS # Content & SEO npx astro add mdx # MDX — Markdown + JSX/React-Komponenten npx astro add sitemap # Automatische sitemap.xml Generierung # Bild-Optimierung npx astro add @astrojs/image # WebP/AVIF Konvertierung + lazy loading

astro.config.mjs — Mehrere Integrationen

// astro.config.mjs import { defineConfig } from 'astro/config'; import react from '@astrojs/react'; import vue from '@astrojs/vue'; import tailwind from '@astrojs/tailwind'; import mdx from '@astrojs/mdx'; import sitemap from '@astrojs/sitemap'; import { defineConfig } from 'astro/config'; export default defineConfig({ site: 'https://meine-website.de', integrations: [ react(), vue(), tailwind({ applyBaseStyles: false }), mdx({ syntaxHighlight: 'shiki', shikiConfig: { theme: 'github-dark' }, remarkPlugins: [remarkReadingTime], rehypePlugins: [rehypeAutolinkHeadings], }), sitemap({ filter: page => !page.includes('/draft/'), changefreq: 'weekly', priority: 0.7, }), ], image: { service: { entrypoint: 'astro/assets/services/sharp' }, }, vite: { plugins: [], build: { cssCodeSplit: true }, }, });

MDX: Markdown mit Komponenten

{/* src/content/blog/mdx-beispiel.mdx */} --- title: MDX in Astro — Interaktive Docs publishedAt: 2026-05-06 --- import CodePlayground from '../../components/CodePlayground'; import Callout from '../../components/Callout.astro'; ## Normale Markdown-Überschrift Normaler Markdown-Text mit **Bold** und _Italic_. <Callout type="warning"> MDX erlaubt es, React/Astro-Komponenten direkt im Markdown zu nutzen! </Callout> <CodePlayground client:visible code={`const greeting = 'Hallo Astro!'; console.log(greeting);`} /> ## Weiter mit normalem Markdown...

@astrojs/image — Automatische Bildoptimierung

--- import { Image, Picture } from 'astro:assets'; import heroImage from '../assets/hero.jpg'; --- <!-- Automatisch: WebP-Konvertierung, lazy loading, korrekte width/height --> <Image src={heroImage} alt="Hero Bild" width={1200} height={630} format="webp" quality={85} loading="lazy" /> <!-- Picture = automatische Art-Direction + mehrere Formate --> <Picture src={heroImage} alt="Responsive Hero" formats={['avif', 'webp']} widths={[400, 800, 1200]} />

6. View Transitions & Deploy: Smooth Navigation & Production

View Transitions Vercel Cloudflare

Astro's View Transitions API verwandelt eine statische Multi-Page-App (MPA) in eine SPA-ähnliche Erfahrung mit flüssigen Seitenübergängen — ohne das gesamte JavaScript-Bundle einer echten SPA laden zu müssen. Der ClientRouter übernimmt die Navigation und animiert DOM-Elemente automatisch.

ClientRouter & transition:animate

// src/layouts/BaseLayout.astro — View Transitions global aktivieren --- import { ClientRouter } from 'astro:transitions'; interface Props { title: string; } const { title } = Astro.props; --- <html lang="de"> <head> <title>{title}</title> <!-- Aktiviert MPA View Transitions für alle Seitenwechsel --> <ClientRouter /> </head> <body> <slot /> </body> </html>
// src/pages/blog/[slug].astro — Morphing-Animation für Hero-Bild --- import { Image } from 'astro:assets'; const { post } = Astro.props; --- <!-- transition:name = eindeutiger Key für Morph-Animation --> <h1 transition:name={`title-${post.slug}`}>{post.data.title}</h1> <Image src={post.data.image.src} alt={post.data.image.alt} width={1200} height={630} transition:name={`hero-${post.slug}`} /> <!-- Benutzerdefinierte Animation --> <aside transition:animate="slide"> Sidebar-Inhalt gleitet rein </aside> <main transition:animate="fade"> Hauptinhalt blendet über </main>

Custom View Transition Animations

// Eigene Animationen mit CSS @keyframes --- import { fade, slide } from 'astro:transitions'; --- <!-- Built-in Animationen --> <div transition:animate={fade({ duration: '0.3s' })}>...</div> <div transition:animate={slide({ duration: '0.25s' })}>...</div> <style> /* Eigene Animation per CSS */ ::view-transition-old(hero-image) { animation: 200ms ease-in-out both scale-out; } ::view-transition-new(hero-image) { animation: 300ms ease-in-out both scale-in; } @keyframes scale-out { from { transform: scale(1); } to { transform: scale(0.95); opacity: 0; } } @keyframes scale-in { from { transform: scale(0.95); opacity: 0; } to { transform: scale(1); } } </style>

Deployment: Vercel, Netlify & Cloudflare

# Vercel (empfohlen für SSR + Edge Functions) npx astro add @astrojs/vercel # astro.config.mjs: adapter: vercel(), output: 'server' vercel deploy # Netlify (SSR via Netlify Functions) npx astro add @astrojs/netlify # astro.config.mjs: adapter: netlify() netlify deploy --prod # Cloudflare Pages (Edge Runtime — schnellstes Deploy) npx astro add @astrojs/cloudflare # astro.config.mjs: adapter: cloudflare({ mode: 'directory' }) npx wrangler pages deploy ./dist # Statisches Deploy (output: 'static') — kein Adapter nötig npm run build # dist/ auf beliebiges CDN: S3, GitHub Pages, Surge.sh...

Claude Code & Astro: Optimaler Workflow

# Claude Code generiert komplette Astro-Projekte in Minuten: # 1. Projektstruktur + Config claude code "Erstelle ein Astro-Blog mit TypeScript, Tailwind, MDX und React-Islands. Konfiguriere Content Collections mit Zod-Schema für Posts mit title, description, publishedAt, tags, image (optional), draft. Füge SEO-Layout mit OG-Tags hinzu." # 2. Einzelne Komponenten claude code "Erstelle eine Astro-Seite src/pages/blog/[slug].astro die: - getStaticPaths() mit getCollection('blog') nutzt - View Transitions mit transition:name für Titel + Hero-Bild hat - Ein Reading-Progress-Bar als React-Island (client:load) einbindet" # 3. Spezifische Features claude code "Füge RSS Feed (src/pages/rss.xml.ts) und Sitemap-Integration hinzu. Generiere außerdem einen automatischen OG-Image-Generator als API-Route."

Astro — Ideal für

  • Blogs & Content-Seiten
  • Marketing-Landing-Pages
  • Dokumentations-Portale
  • E-Commerce Produktseiten
  • Portfolio-Websites
  • SEO-kritische Projekte

Weniger geeignet für

  • Hochinteraktive Web-Apps
  • Real-time Dashboards
  • Chat-Applikationen
  • Komplexe SPA-Flows
  • Browser-Games
  • Collaboration-Tools

Performance-Vergleich: Astro vs. Next.js vs. Nuxt

Astro-Projekte mit Claude Code automatisieren

Islands Architecture, typsichere Content Collections, View Transitions und optimales Deployment — Claude Code versteht die moderne Astro-Architektur und generiert produktionsreifen Code für blitzschnelle Websites. Jetzt kostenlos testen und die erste Astro-Site in Minuten aufsetzen.

14 Tage kostenlos testen →