Home›
Blog›
Astro mit Claude Code: Static Sites & Islands Architecture 2026
Astro hat in wenigen Jahren die Welt der Web-Entwicklung auf den Kopf gestellt. Mit dem revolutionären Islands-Ansatz liefert Astro Websites aus, die standardmäßig kein JavaScript zum Browser senden — und trotzdem React, Svelte, Vue oder Solid einbinden können, genau dort, wo Interaktivität wirklich gebraucht wird. 2026 ist Astro 5 die erste Wahl für Content-heavy Sites, Marketing Pages, Blogs und Dokumentationen.
Claude Code versteht die Astro-Philosophie und kann innerhalb von Sekunden vollständige Projekte scaffolden, Komponenten refaktorieren und Performance-Bottlenecks identifizieren. In diesem Guide zeigen wir, wie das Duo Astro + Claude Code die Entwicklung von Static Sites 2026 neu definiert.
Warum Astro 2026? Lighthouse-Score 100/100 out of the box, Zero-JS by default, native TypeScript, Content Collections mit Zod-Schemas, Server Islands für hybrides Rendering — und eine der aktivsten Communities im JS-Ökosystem.
1 Astro 5 Grundlagen — Setup & Komponenten-Syntax
Der Einstieg in Astro ist bewusst einfach gehalten. Mit einem einzigen Befehl entsteht ein produktionsreifes Projekt-Skelett — inklusive TypeScript-Konfiguration, ESLint und optionalen Integrationen.
Projekt erstellen mit Claude Code
Claude Code führt den Setup-Prozess vollautomatisch durch und fragt bei Unklarheiten nach:
# Neues Astro-Projekt starten
npm create astro@latest meine-website
# Interaktive Auswahl im Terminal:
✔ Which template? › Minimal
✔ Use TypeScript? › Yes (strict)
✔ Install dependencies? › Yes
✔ Initialize git? › Yes
# Integrationen nachträglich hinzufügen
npx astro add react tailwind sitemap
Das erzeugte Projekt-Skelett ist minimal und sauber. Claude Code versteht die Verzeichnisstruktur sofort und kann gezielt in einzelne Bereiche eingreifen:
meine-website/
├── src/
│ ├── components/ # Wiederverwendbare .astro Komponenten
│ ├── layouts/ # Seiten-Layouts mit <slot />
│ ├── pages/ # File-based Routing (.astro, .md, .mdx)
│ └── content/ # Content Collections (KW19+)
├── public/ # Statische Assets (favicon, fonts)
├── astro.config.mjs # Haupt-Konfiguration
└── tsconfig.json # TypeScript strict mode
Die .astro Komponenten-Syntax
Astro-Komponenten verbinden HTML-Templates mit einem JavaScript-Frontmatter-Block, der beim Build auf dem Server ausgeführt wird. Das Ergebnis ist reines, statisches HTML — kein Runtime-Overhead.
---
# src/components/BlogCard.astro
---
interface Props {
title: string;
excerpt: string;
date: Date;
slug: string;
category: string;
}
const { title, excerpt, date, slug, category } = Astro.props;
const formattedDate = date.toLocaleDateString('de-DE', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
---
<article class="blog-card">
<span class="category-badge">{category}</span>
<h2><a href={`/blog/${slug}/`}>{title}</a></h2>
<p>{excerpt}</p>
<time datetime={date.toISOString()}>{formattedDate}</time>
</article>
<style>
/* Scoped CSS — gilt NUR für diese Komponente */
.blog-card { border: 1px solid #e2e8f0; border-radius: 8px; padding: 24px; }
.category-badge { background: #6366f1; color: white; padding: 2px 10px; border-radius: 12px; }
</style>
Astro-Feature Scoped CSS ohne Build-Tool-Konfiguration
Jede .astro-Datei kann einen <style>-Block enthalten. Astro scopet die Styles automatisch auf die Komponente — kein CSS-Modules-Setup, kein BEM, keine Klassen-Konflikte. Im Build wird daraus ein minimiertes, kritisches CSS-Bundle.
astro.config.mjs — Die Schaltzentrale
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
import tailwind from '@astrojs/tailwind';
import sitemap from '@astrojs/sitemap';
import vercel from '@astrojs/vercel/serverless';
export default defineConfig({
site: 'https://meine-website.de',
integrations: [
react(),
tailwind({ applyBaseStyles: false }),
sitemap(),
],
output: 'static', // 'server' für SSR, 'hybrid' für Mix
adapter: vercel(),
image: {
service: { entrypoint: 'astro/assets/services/sharp' },
},
vite: {
plugins: [],
}
});
⚡
Vite unter der Haube
Astro nutzt Vite als Build-Tool — blitzschnelle HMR, Tree-Shaking und optimale Bundle-Sizes inklusive.
🔒
TypeScript strict
Props, Frontmatter und Content Collections sind vollständig typisiert. Claude Code versteht die Typen und schlägt korrekte Signaturen vor.
📁
File-based Routing
src/pages/blog/[slug].astro erzeugt automatisch dynamische Routen — konventionsbasiert, ohne Router-Konfiguration.
2 Islands Architecture — Framework-Inseln im HTML-Ozean
Islands
React
Svelte
Vue
Das Herzstück von Astro ist die Islands Architecture: Die Seite wird als reines, statisches HTML ausgeliefert. Nur explizit markierte Komponenten — die "Inseln" — laden JavaScript nach und werden im Browser hydriert. Das Ergebnis: drastisch reduzierte Bundle-Sizes, schnellere Ladezeiten und bessere Core Web Vitals.
Das Prinzip: "Ship Zero JS by Default." Interaktivität ist opt-in, nicht opt-out. Während klassische SPAs den gesamten JavaScript-Bundle laden bevor irgendetwas sichtbar wird, zeigt Astro sofort den Inhalt und hydratisiert nur einzelne Komponenten auf Anforderung.
Hydration Directives — Kontrolle über das Wann
Astro bietet fünf Hydration-Direktiven, die steuern, wann und wie eine Komponente im Browser zum Leben erwacht:
---
# src/pages/index.astro
import { Navbar } from '../components/Navbar.astro';
import KontaktFormular from '../components/KontaktFormular.tsx';
import Testimonials from '../components/Testimonials.svelte';
import LiveChat from '../components/LiveChat.vue';
import AnalyticsWidget from '../components/AnalyticsWidget.tsx';
---
<!-- Kein JS — wird als reines HTML gerendert -->
<Navbar />
<!-- client:load — sofort hydrieren, höchste Priorität -->
<KontaktFormular client:load />
<!-- client:idle — nach requestIdleCallback (non-critical) -->
<LiveChat client:idle />
<!-- client:visible — erst wenn im Viewport (IntersectionObserver) -->
<Testimonials client:visible />
<!-- client:media — nur wenn Media Query matched -->
<AnalyticsWidget client:media="(min-width: 1024px)" />
<!-- client:only — nur client-side, kein SSR (z.B. window-abhängig) -->
<LiveChat client:only="react" />
island React-Komponente in Astro einbinden
Framework-Komponenten funktionieren genau wie gewohnt — Props, Hooks, State alles inklusive. Astro kümmert sich um die Hydration-Infrastruktur.
// src/components/KontaktFormular.tsx — normale React-Komponente
import { useState } from 'react';
interface FormData {
name: string;
email: string;
nachricht: string;
}
export default function KontaktFormular() {
const [formData, setFormData] = useState<FormData>({
name: '', email: '', nachricht: ''
});
const [status, setStatus] = useState<'idle' | 'loading' | 'success'>('idle');
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
setStatus('loading');
await fetch('/api/kontakt', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData),
});
setStatus('success');
}
if (status === 'success') return <p>Danke! Wir melden uns bald.</p>;
return (
<form onSubmit={handleSubmit}>
<input value={formData.name} onChange={e => setFormData({...formData, name: e.target.value})} placeholder="Dein Name" />
<button type="submit" disabled={status === 'loading'}>Senden</button>
</form>
);
}
Performance-Vergleich: SPA vs. Islands
| Metrik |
Next.js SPA |
Astro Islands |
Vorteil |
| Initial JS Bundle |
~250 KB (gzip) |
~0 KB |
100% |
| Time to First Byte |
~200ms |
~40ms |
5× schneller |
| Largest Contentful Paint |
~2.1s |
~0.6s |
3.5× besser |
| Lighthouse Performance |
65–80 |
95–100 |
+20 Punkte |
| React/Svelte/Vue Support |
✓ (React native) |
✓ (alle parallel) |
Astro flexibler |
3 Content Collections — Type-safe Inhalte mit Zod
Collections
Zod
TypeScript
Content Collections sind Astros typisiertes CMS-System. Markdown- und MDX-Dateien werden mit Zod-Schemas validiert und stehen danach vollständig typisiert zur Verfügung. Keine Runtime-Fehler durch fehlende Frontmatter-Felder mehr.
Schema definieren
// src/content/config.ts — Zentrale Schema-Definitionen
import { defineCollection, z } from 'astro:content';
const blogCollection = defineCollection({
type: 'content',
schema: z.object({
title: z.string().min(10).max(100),
description: z.string().max(200),
publishDate: z.coerce.date(),
updatedDate: z.coerce.date().optional(),
author: z.string().default('SpockyMagicAI Team'),
category: z.enum(['KI', 'Web', 'Tools', 'Tutorial']),
tags: z.array(z.string()).default([]),
draft: z.boolean().default(false),
image: z.object({
src: z.string(),
alt: z.string(),
}).optional(),
readTime: z.number().int().positive(), // Minuten
}),
});
const teamCollection = defineCollection({
type: 'data',
schema: z.object({
name: z.string(),
rolle: z.string(),
bio: z.string(),
avatar: z.string().url(),
social: z.object({
twitter: z.string().optional(),
github: z.string().optional(),
}),
}),
});
export const collections = {
blog: blogCollection,
team: teamCollection,
};
Inhalte abrufen und rendern
---
# src/pages/blog/index.astro
import { getCollection } from 'astro:content';
import Layout from '../../layouts/BaseLayout.astro';
import BlogCard from '../../components/BlogCard.astro';
// Alle veröffentlichten Blog-Posts laden und sortieren
const allPosts = await getCollection('blog', ({ data }) => {
return !data.draft; // Drafts filtern
});
const sortedPosts = allPosts.sort(
(a, b) => b.data.publishDate.valueOf() - a.data.publishDate.valueOf()
);
// Nach Kategorien gruppieren
const byCategory = sortedPosts.reduce((acc, post) => {
const cat = post.data.category;
acc[cat] = [...(acc[cat] ?? []), post];
return acc;
}, {} as Record<string, typeof sortedPosts>);
---
<Layout title="Blog">
<div class="blog-grid">
{sortedPosts.map(post => (
<BlogCard
title={post.data.title}
excerpt={post.data.description}
date={post.data.publishDate}
slug={post.slug}
category={post.data.category}
/>
))}
</div>
</Layout>
---
# src/pages/blog/[slug].astro — Dynamische Post-Seite
import { getCollection, getEntry } from 'astro:content';
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 } = await post.render();
// Verwandte Posts laden
const related = await getCollection('blog', ({ data, slug }) =>
data.category === post.data.category && slug !== post.slug
);
---
<article>
<h1>{post.data.title}</h1>
<Content /> <!-- MDX/Markdown wird zu React-Komponenten -->
</article>
Tipp Claude Code + Content Collections
Claude Code versteht Zod-Schemas und kann daraus automatisch TypeScript-Typen, Validierungslogik und sogar Test-Fixtures generieren. Beschreibe einfach die Datenstruktur in natürlicher Sprache: "Erstelle ein Schema für Blog-Posts mit Titel, Datum, Tags und optionalem Hero-Bild" — und Claude Code liefert den vollständigen, typsierten Collection-Code.
4 Server Actions & SSR — Dynamik wo sie gebraucht wird
SSR
Actions
API Routes
Astro 5 führt Server Actions als First-Class-Feature ein: typisierte, serverseitige Funktionen, die direkt aus Komponenten aufgerufen werden können. Kein Boilerplate für API-Routes mehr bei einfachen Formularen und CRUD-Operationen.
Hybrid Rendering: Mit output: 'hybrid' kann jede Seite individuell zwischen statischem und serverseitigem Rendering wählen. export const prerender = false macht eine einzelne Seite dynamisch, ohne den Rest der Site zu beeinflussen.
Server Actions definieren
// src/actions/index.ts
import { defineAction } from 'astro:actions';
import { z } from 'astro:schema';
export const server = {
newsletter: {
subscribe: defineAction({
accept: 'form',
input: z.object({
email: z.string().email('Ungültige E-Mail-Adresse'),
vorname: z.string().min(2),
}),
handler async({ email, vorname }) {
// Direkt Datenbankzugriff — kein separater API-Endpunkt nötig
await db.insert(subscribers).values({ email, vorname,
subscribedAt: new Date()
});
await sendWelcomeEmail(email, vorname);
return { success: true, message: `Willkommen, ${vorname}!` };
},
}),
},
contact: {
send: defineAction({
accept: 'json',
input: z.object({
name: z.string(),
email: z.string().email(),
nachricht: z.string().min(20),
betreff: z.enum(['Support', 'Partnerschaft', 'Presse']),
}),
handler async(data, context) {
const ip = context.request.headers.get('x-forwarded-for');
await rateLimit(ip, 'contact', 5); // Max 5 pro Stunde
await sendToSlack(data);
return { ticket: crypto.randomUUID() };
},
}),
},
};
Actions in Komponenten nutzen
---
# src/components/NewsletterForm.astro
import { actions } from 'astro:actions';
// Progressive Enhancement: funktioniert auch ohne JS!
const result = Astro.getActionResult(actions.newsletter.subscribe);
---
<form method="POST" action={actions.newsletter.subscribe}>
<input type="email" name="email" required placeholder="deine@email.de" />
<input type="text" name="vorname" required placeholder="Vorname" />
<button type="submit">Newsletter abonnieren</button>
{result?.error && <p class="error">{result.error.message}</p>}
{result?.data?.success && <p class="success">{result.data.message}</p>}
</form>
API Routes für komplexe Anwendungsfälle
// src/pages/api/search.ts — REST-Endpunkt
import type { APIRoute } from 'astro';
import { getCollection } from 'astro:content';
export const GET: APIRoute = async ({ request }) => {
const url = new URL(request.url);
const query = url.searchParams.get('q')?.toLowerCase() ?? '';
if (!query || query.length < 2) {
return new Response(
JSON.stringify({ error: 'Mindestens 2 Zeichen' }),
{ status: 400, headers: { 'Content-Type': 'application/json' } }
);
}
const posts = await getCollection('blog', ({ data }) => !data.draft);
const results = posts.filter(post =>
post.data.title.toLowerCase().includes(query) ||
post.data.description.toLowerCase().includes(query) ||
post.data.tags.some(tag => tag.toLowerCase().includes(query))
).slice(0, 10);
return new Response(JSON.stringify(results.map(p => ({
slug: p.slug,
title: p.data.title,
description: p.data.description,
}))), { headers: { 'Content-Type': 'application/json' } });
};
SSR Cookies & Session Management
Im SSR-Modus stellt Astro.cookies eine komfortable API für HTTP-Cookies bereit. Claude Code kann daraus vollständige Auth-Flows mit JWT-Tokens, Session-Cookies und CSRF-Protection generieren — in wenigen Minuten.
Astro.cookies.get('session')?.value — Cookie lesen
Astro.cookies.set('session', token, { httpOnly: true }) — Cookie setzen
Astro.redirect('/login') — Redirect bei fehlendem Auth
5 View Transitions — Flüssige Navigation ohne SPA-Overhead
View Transitions
Animation
ClientRouter
View Transitions sind einer der spektakulärsten Features moderner Webentwicklung — und Astro macht sie erschreckend einfach. Statt einer vollständigen SPA-Architektur nutzt Astro die native View Transitions API des Browsers für flüssige Seitenübergänge bei MPA-Sites.
ClientRouter aktivieren
---
# src/layouts/BaseLayout.astro — Einmalige Aktivierung im Layout
import { ClientRouter } from 'astro:transitions';
---
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<ClientRouter /> <!-- Das ist alles! Navigation wird automatisch intercepted -->
<title>{Astro.props.title}</title>
</head>
<body>
<slot />
</body>
</html>
Animationen mit transition:animate
---
# src/pages/blog/[slug].astro — Animierte Blog-Post-Seite
import { fade, slide, morph } from 'astro:transitions';
---
<!-- Slide-In von rechts beim Öffnen eines Blog-Posts -->
<main transition:animate="slide">
<h1 transition:animate={fade({ duration: '0.3s' })}>
{post.data.title}
</h1>
<!-- Hero-Bild "morpht" nahtlos zwischen Listen- und Detail-Ansicht -->
<img
src={post.data.image?.src}
transition:name={`hero-${post.slug}`}
transition:animate="morph"
/>
</main>
---
# src/pages/blog/index.astro — Artikel-Liste mit passenden transition:name
---
{allPosts.map(post => (
<article>
<!-- Gleiches transition:name → Browser morpht das Bild beim Navigieren -->
<img
src={post.data.image?.src}
transition:name={`hero-${post.slug}`}
/>
<h2><a href={`/blog/${post.slug}/`}>{post.data.title}</a></h2>
</article>
))}
Persistente Inseln — Navigation ohne State-Verlust
<!-- Audio-Player bleibt bei Navigation aktiv -->
<PodcastPlayer
client:load
transition:persist
transition:name="podcast-player"
/>
<!-- Warenkorb bleibt ohne State-Reset -->
<Warenkorb
client:idle
transition:persist="warenkorb"
/>
Kompatibilität Graceful Degradation
Die View Transitions API wird von modernen Browsern unterstützt (Chrome 111+, Safari 18+, Firefox 130+). Astros ClientRouter implementiert automatisch einen Fallback für ältere Browser — die Navigation funktioniert dann ohne Animationen, aber das Rendering bleibt korrekt.
Lifecycle Events: Astro feuert Custom Events während Transitions (astro:before-preparation, astro:after-swap, astro:page-load), mit denen Analytics-Tracking, A/B-Tests und progressive Enhancement sauber integriert werden können.
6 Deployment — Vercel, Netlify & Lighthouse 100
Vercel
Netlify
Image Optimization
Lighthouse 100
Astro-Projekte lassen sich auf allen modernen Hosting-Plattformen deployen. Für die optimale Developer Experience empfehlen sich Vercel oder Netlify — beide bieten offizielle Astro-Adapter mit vollständiger Edge-Functions-Unterstützung.
Vercel Deployment
# 1. Adapter installieren
npm install @astrojs/vercel
# 2. astro.config.mjs anpassen
import vercel from '@astrojs/vercel/serverless';
export default defineConfig({
output: 'server',
adapter: vercel({
imageService: true, // Vercel Image Optimization nutzen
edgeMiddleware: true, // Middleware auf Edge laufen lassen
isr: { // Incremental Static Regeneration
expiration: 60 * 60, // 1 Stunde Cache
},
}),
});
# 3. Deployen
npx vercel --prod
Netlify mit Edge Functions
# Netlify Adapter
npm install @astrojs/netlify
import netlify from '@astrojs/netlify';
export default defineConfig({
output: 'server',
adapter: netlify({
edgeMiddleware: true,
cacheOnDemandPages: true,
}),
});
# netlify.toml — Erweiterte Cache-Strategie
[[headers]]
for = "/blog/*"
[headers.values]
Cache-Control = "public, max-age=3600, stale-while-revalidate=86400"
Astro Image — Automatische Bildoptimierung
---
# Astro:assets — Eingebaute Bildoptimierung
import { Image, Picture } from 'astro:assets';
import heroImage from '../../assets/hero.jpg';
---
<!-- Automatisch: WebP-Konvertierung, srcset, lazy loading, korrekte Dimensionen -->
<Image
src={heroImage}
alt="Astro Framework Hero"
width={1200}
height={630}
format="webp"
quality={85}
loading="eager"
/>
<!-- Responsive Bildformat-Set für verschiedene Viewports -->
<Picture
src={heroImage}
formats={['avif', 'webp', 'jpeg']}
alt="Hero Bild"
widths={[400, 800, 1200]}
/>
Lighthouse 100 — Checkliste
Performance Was Astro automatisch richtig macht
- Critical CSS inlining: Astro extrahiert und inlinet das kritische CSS automatisch
- Script Bundling: Nur das JS, das tatsächlich genutzt wird, wird gebundelt
- Preload hints: Fonts, Bilder und Scripts werden mit korrekten
<link rel="preload"> versehen
- Zero-layout-shift:
astro:assets setzt width/height automatisch (kein CLS)
- Kompression: Vercel/Netlify aktivieren Brotli/gzip automatisch
# Lokaler Lighthouse-Test vor dem Deploy
npm install -g lighthouse
# Production Build starten
npm run build && npm run preview
# Lighthouse CLI ausführen
lighthouse http://localhost:4321 \
--only-categories=performance,accessibility,best-practices,seo \
--output=html \
--output-path=./lighthouse-report.html
# Ziel: Performance ≥ 95, Accessibility = 100, SEO = 100
CI/CD Pipeline mit GitHub Actions
# .github/workflows/deploy.yml
name: Deploy to Vercel
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20' }
- run: npm ci
- run: npm run build
- run: npm run test
- name: Deploy to Vercel
if: github.ref == 'refs/heads/main'
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
run: npx vercel --prod --token=$VERCEL_TOKEN
🌐
Edge Deployment
Mit @astrojs/vercel/edge läuft jede Seite am nächsten PoP — globale Latenz unter 50ms möglich.
🖼️
Image CDN
Vercel Image Optimization und Cloudinary-Integration wandeln Bilder on-demand in WebP/AVIF um — mit automatischem Caching.
📊
Analytics
Vercel Analytics und Web Vitals Monitoring lassen sich mit zwei Zeilen Code in jedes Astro-Projekt einbinden.
Fazit — Warum Astro + Claude Code 2026 unschlagbar ist
Astro 5 hat den Static-Site-Generator-Markt neu definiert. Mit Islands Architecture, Content Collections, Server Actions und View Transitions bietet es die Performance von statischen Sites bei der Flexibilität moderner Web-Frameworks. Die Lernkurve ist flach, die Entwicklerergonomie exzellent.
Claude Code beschleunigt die Astro-Entwicklung dramatisch: Komponenten werden aus Natürlichsprache-Beschreibungen generiert, Schemas automatisch typisiert, Performance-Probleme sofort identifiziert. Der Workflow von der Idee zur Produktion schrumpft von Tagen auf Stunden.
Ob Marketing-Seite, Blog, Dokumentation oder hybride Web-App — Astro ist 2026 die technisch überlegene Wahl, und Claude Code der perfekte Entwicklungspartner dafür.
Quick Start mit Claude Code: Öffne Claude Code, tippe "Erstelle ein Astro 5 Projekt mit TypeScript, Tailwind, Content Collections für Blog-Posts und einer React-Island für das Kontaktformular" — und lehne dich zurück.
Bereit, mit Astro & Claude Code zu starten?
Starte deine kostenlose Trial und erlebe, wie Claude Code komplette Astro-Projekte in Minuten scaffoldet, refaktoriert und deployed — ohne Copy-Paste, ohne Dokumentation wälzen.
Kostenlose Trial starten →