Moderne Webentwicklung mit Astro & Svelte – Interaktive Inseln ganz ohne Overhead
Astro und Svelte kombinieren ultraschnelle statische Seiten mit punktueller Interaktivität – ohne unnötigen JavaScript-Overhead. Ein Praxisüberblick für 2025.
Astro und Svelte – das klingt auf den ersten Blick nach zwei getrennten Welten. Doch zusammen liefern sie eines der elegantesten Webentwicklungserlebnisse, das es derzeit gibt: ultraschnell, maximal kontrollierbar, minimal JavaScript – und trotzdem vollständig interaktiv, wenn es gebraucht wird.
In diesem Artikel im Fokus:
Interaktive Komponenten Svelte-Stores für State Management Server Islands & API-Integration Tailwind als optionales Styling-Tool
Was ist Astro?
Astro ist ein modernes, komponentenbasiertes Static Site Framework, das HTML-first denkt. Es generiert superschnelles HTML zur Build-Zeit, verschickt standardmäßig kein JavaScript in den Browser und ist dadurch ideal für Performance, SEO und Accessibility.
- Rendering-Modi: Static, SSR, Hybrid
- Framework-flexibel: Nutzt React, Vue, Svelte, Solid etc. modular
- Partial Hydration: Nur laden, was gebraucht wird – per „Island Architecture“
Was bringt Svelte in ein Astro-Projekt?
Svelte ergänzt Astro perfekt – und zwar dort, wo HTML nicht mehr reicht:
- Interaktivität: Formulare, Filter, Dropdowns, Sliders
- Zustand: Reaktives Verhalten mit minimalem Code
- Komponentenstruktur: Saubere Trennung von Logik und Darstellung
Svelte wird von Astro wie ein Plugin eingebunden und nur dort aktiviert, wo es explizit gewünscht ist:
npm install @astrojs/svelte
In der astro.config.mjs:
import svelte from '@astrojs/svelte';
export default {
integrations: [svelte()],
};
Interaktive Komponenten – gezielt laden
Astro verwendet sog. Client Directives, um festzulegen, wann eine Komponente interaktiv wird:
---
import Counter from '../components/Counter.svelte';
---
<Counter client:visible />
Die wichtigsten Client Directives:
client:load– Sofort beim Seitenaufbau laden (für Above-the-Fold-Interaktivität)client:idle– Laden, wenn der Browser idle ist (gut für nicht-kritische Features)client:visible– Erst laden, wenn die Komponente im Viewport ist (optimal für Performance)client:media– Nur bei bestimmten Media Queries laden (z.B.client:media="(max-width: 768px)")client:only– Nur clientseitig rendern, kein SSR (für Browser-spezifische APIs)
In Counter.svelte:
<script>
let count = 0;
</script>
<button on:click={() => count++}>Geklickt: {count}</button>
Der Code wird nur geladen, wenn die Komponente sichtbar wird – kein unnötiges JavaScript im Head.
Zustand mit Svelte-Stores
Kein Redux, kein Vuex, keine Boilerplate. Mit writable() ist sofort alles bereit:
// stores/ui.js
import { writable } from 'svelte/store';
export const isModalOpen = writable(false);
In beliebigen Komponenten:
<script>
import { isModalOpen } from '../stores/ui.js';
</script>
{#if $isModalOpen}
<div class="modal">Ich bin offen!</div>
{/if}
Astro bleibt davon komplett unberührt – das ist echte Kapselung.
Server Islands – dynamisch und performant
Seit Astro 4+ lassen sich mit sogenannten Server Islands kleine serverseitig gerenderte Komponenten direkt auf Seiten einsetzen – z. B. um Daten aus APIs zu laden, ohne die ganze Seite serverseitig zu betreiben.
Beispiel:
---
// LatestPosts.astro (Server Island)
const res = await fetch('https://example.com/api/posts');
const posts = await res.json();
---
<ul>
{
posts.map((post) => (
<li>
<a href={`/blog/${post.slug}`}>{post.title}</a>
</li>
))
}
</ul>
Das Listing kann serverseitig in Astro erfolgen – und das „Like“-Feature clientseitig per Svelte. So wird das Beste aus beiden Welten kombiniert.
Styling mit Tailwind (optional, aber empfehlenswert)
Tailwind passt perfekt ins Astro-Universum:
- Utility-first
- Purge beim Build
- Funktioniert in
.astro,.svelte,.mdx, überall
Einbinden:
npm install -D tailwindcss
npx tailwindcss init
In der astro.config.mjs:
import tailwind from '@astrojs/tailwind';
export default {
integrations: [tailwind()],
};
Dann einfach verwenden:
<button class="bg-blue-600 text-white rounded p-2 hover:bg-blue-700">
Click me
</button>
Sogar innerhalb von .svelte-Dateien funktioniert Tailwind reibungslos.
Performance-Vorteile in der Praxis
Die Kombination Astro + Svelte liefert messbare Ergebnisse:
Bundle-Size Vergleich (typisches Blog/Marketing-Projekt):
- Next.js (React): ~85KB (gzip) JavaScript Baseline
- Nuxt (Vue): ~75KB (gzip) JavaScript Baseline
- Astro + Svelte: ~2-5KB (gzip) nur für interaktive Komponenten
Lighthouse Scores ohne Tuning:
- Performance: 95-100 (durch statisches HTML)
- SEO: 100 (perfektes Meta-Handling)
- Accessibility: 90+ (wenn vernünftig entwickelt)
- Best Practices: 100
Real-World-Beispiel: Eine typische Marketing-Seite mit Navigation, Hero, Features, Contact-Form:
- Mit Next.js: ~120KB JavaScript + 45KB für Form-Handling
- Mit Astro + Svelte: ~8KB nur für das Contact-Form
Das bedeutet 93% weniger JavaScript bei identischer Funktionalität.
Praxis-Beispiel: Interaktives Feature-Panel
Ein typisches Szenario: Tabs mit Content-Wechsel.
<script>
import { writable } from 'svelte/store';
let activeTab = writable('features');
const tabs = [
{ id: 'features', label: 'Features' },
{ id: 'pricing', label: 'Preise' },
{ id: 'faq', label: 'FAQ' }
];
</script>
<div class="tabs">
{#each tabs as tab}
<button
class:active={$activeTab === tab.id}
on:click={() => activeTab.set(tab.id)}
>
{tab.label}
</button>
{/each}
</div>
<div class="content">
{#if $activeTab === 'features'}
<slot name="features" />
{:else if $activeTab === 'pricing'}
<slot name="pricing" />
{:else}
<slot name="faq" />
{/if}
</div>
In der .astro-Seite:
---
import FeaturePanel from '../components/FeaturePanel.svelte';
---
<FeaturePanel client:visible>
<div slot="features">
<h3>Unsere Features</h3>
<p>Blitzschnell, flexibel, wartbar</p>
</div>
<div slot="pricing">
<h3>Faire Preise</h3>
<p>Keine versteckten Kosten</p>
</div>
<div slot="faq">
<h3>Häufige Fragen</h3>
<p>Alle Antworten auf einen Blick</p>
</div>
</FeaturePanel>
Der Clou: Content wird in Astro definiert (SEO-freundlich), Interaktivität kommt von Svelte (nur wenn sichtbar).
Svelte vs. Alpine in Astro?
Svelte ist nicht einfach nur ein Alpine.js-Ersatz – sondern ein vollständiges reaktives UI-Framework.
Alpine:
- Direkt im HTML
- Schnell für Mikro-Interaktionen
- Kein Build-Tool nötig
Svelte:
- Für komplexe UIs, wiederverwendbare Komponenten
- Reaktives System, Stores, Effekte
- Höhere Wartbarkeit & Skalierbarkeit
Für 2–3 Buttons reicht Alpine. Für komplexere Anforderungen ist Svelte das Werkzeug der Wahl.
Häufige Fallstricke & Lösungen
1. Svelte-Stores funktionieren nicht zwischen Komponenten
Problem: Jede Instanz hat eigenen Store-State.
Lösung: Store außerhalb der Komponente definieren:
// ❌ Falsch - in der Komponente
<script>
import { writable } from 'svelte/store';
const count = writable(0); // Jede Instanz hat eigenen State
</script>
// ✅ Richtig - in separater Datei
// stores/counter.js
import { writable } from 'svelte/store';
export const count = writable(0);
2. Client Directives vergessen
Ohne client:* bleibt die Komponente statisches HTML – Event-Handler funktionieren nicht.
<!-- ❌ Nicht interaktiv -->
<MyButton />
<!-- ✅ Interaktiv -->
<MyButton client:load />
3. Props zwischen Astro und Svelte
Nur JSON-serialisierbare Daten funktionieren:
<!-- ✅ Funktioniert -->
<Component client:load data={{ name: 'Test', count: 42 }} />
<!-- ❌ Funktioniert nicht -->
<Component client:load callback={() => console.log('test')} />
Migration von reinem Astro zu Astro + Svelte
Schritt-für-Schritt ohne große Umbauten:
Phase 1: Setup (5 Minuten)
npm install @astrojs/svelte
Phase 2: Erste interaktive Komponente umbauen
- Kopiere bestehende Astro-Komponente
- Benenne um:
.astro→.svelte - Füge
<script>für Logik hinzu - Nutze
client:visiblein Astro-Page
Phase 3: Stores einführen (wenn nötig)
- Erstelle
src/stores/ - Definiere globalen State
- Importiere in Svelte-Komponenten
Phase 4: Schrittweise erweitern
- Nur komplexe Interaktionen migrieren
- Statische Teile bleiben Astro
Ein letzter Gedanke: Wann Astro + Svelte einsetzen?
| Wunsch | Astro + Svelte ist ideal |
|---|---|
| Superschnelles statisches HTML mit perfektem SEO | ✅ |
| Interaktive Elemente ohne SPA-Ballast | ✅ |
| Einfache Reaktivität ohne Overhead | ✅ |
| Server-Daten nur dort, wo nötig | ✅ |
| Modernes CSS ohne Bloat | ✅ |
TL;DR – Start-Stack 2025
npm create astro@latest
npm install @astrojs/svelte
npm install -D tailwindcss
.astrofür Seiten, Layouts, Meta, SEO.sveltefür alles, was klicken, filtern, togglen oder reagieren mussclient:*Direktiven für gezielte Interaktivität- Optional: Tailwind für Styling, Stores für Zustand, Server Islands für APIs
Mehr zu Best Practices, Astro-Integration und Headless CMS mit Svelte:
Dort gibt es einen Einblick, wie Svelte, Astro und Headless-CMS-Systeme in modernen Webprojekten optimal zusammenspielen.