Astro baut Seiten standardmäßig ohne JavaScript. Trotzdem kannst du React-Komponenten mitten in eine .astro-Datei setzen: Astro rendert sie und schickt nur dort Code an den Browser, wo du es erlaubst. Für animierte Bausteine ist genau diese Erlaubnis der entscheidende Schritt.
- Die Komponenten müssen nicht umgeschrieben werden. Astro rendert React über eine offizielle Integration mit.
- Ohne client-Direktive kommt die Komponente als reines HTML an, und die Animation läuft nicht.
- client:visible ist für Sections unter dem ersten Bildschirm meist die richtige Wahl, client:load für den Hero.
- Astro und React teilen sich dasselbe Tailwind-Setup. Es braucht keine zweite Konfiguration.
Warum das ohne Portierung geht
Astro ist kein eigenes Komponenten-Format, sondern ein Seiten-Framework, das fremde Komponenten aufnimmt. Über sogenannte Integrationen kann es React, Vue, Svelte und andere rendern, auch nebeneinander in derselben Seite.
Für die Library heißt das: Der kopierte TSX-Code bleibt Zeile für Zeile derselbe. Du legst ihn in dein Astro-Projekt und bindest ihn ein. Es gibt keine Astro-Fassung der Komponenten, weil es keine braucht.
Einrichten
Ein Befehl richtet die React-Integration ein und trägt sie in die Konfiguration ein. Danach kommen die drei Pakete dazu, die die Komponenten selbst brauchen.
npx astro add reactnpm install framer-motion lucide-react npx astro add tailwind
Die Komponente einbinden
Die kopierte Datei landet zum Beispiel unter src/components. In der .astro-Seite importierst du sie wie in React und setzt sie in den Markup-Teil.
Der entscheidende Zusatz ist die client-Direktive. Ohne sie rendert Astro die Komponente einmal zu HTML und schickt kein JavaScript mit. Die Seite sieht dann richtig aus, aber nichts bewegt sich, kein Hover reagiert und kein Zustand wechselt.
---import Layout from "../layouts/Layout.astro";import Hero from "../components/ProcurementSplitHero";--- <Layout> <Hero client:load /></Layout>
- Astro rendert einmal zu HTML.
- Kein JavaScript geht an den Browser.
- Die Section sieht richtig aus.
- Nichts bewegt sich, kein Hover reagiert.
- Astro rendert das HTML wie vorher.
- Der Code der Komponente kommt dazu.
- Die Section sieht genauso aus.
- Animation, Hover und Zustand laufen.
Welche client-Direktive wann
Astro kennt mehrere Direktiven. Sie entscheiden, wann der Browser den Code der Komponente lädt und ausführt. Für die Bausteine der Library sind drei davon interessant.
- client:load Lädt sofort. Richtig für alles, was direkt sichtbar ist: der Hero, eine Navigation, ein Knopf über dem Falz.
- client:visible Lädt erst, wenn der Abschnitt in die Nähe des Bildschirms scrollt. Die beste Wahl für alle Sections weiter unten, gerade bei Scroll-Animationen: Sie sollen ohnehin erst dort anspringen.
- client:idle Lädt, sobald der Browser Luft hat. Passt für Nebensächliches, das nicht sofort da sein muss, etwa einen Newsletter-Block im Footer.
Als Faustregel: der erste Bildschirm bekommt client:load, alles darunter client:visible. Damit bleibt die Startlast klein, und trotzdem läuft jede Animation, sobald man sie sieht.
Ohne Direktive: kein JavaScript, keine Bewegung. Mit der falschen: Bewegung, die zu früh oder zu spät startet.
Bilder und Schriften
Die Komponenten binden Bilder als einfache Adresse ein, nicht über einen Bild-Import. Damit funktionieren sie in Astro genauso wie überall sonst: Datei nach public legen, Pfad im Code anpassen, fertig.
Wer Astros eigene Bildoptimierung nutzen will, ersetzt das img-Element in der kopierten Komponente durch das Image-Element aus astro:assets. Das geht allerdings nur in .astro-Dateien, nicht innerhalb der React-Komponente. In dem Fall gibt man das fertige Bild als Property hinein.
---import { Image } from "astro:assets";import bild from "../assets/hero.jpg";--- <Hero client:load bild={bild.src} />
Mehrere Komponenten auf einer Seite
Jede React-Komponente mit client-Direktive ist eine eigene Insel. Sie bringt ihren eigenen Code mit und weiß nichts von den Nachbarn. Für die Bausteine der Library ist das kein Problem, weil sie ohnehin eigenständig sind und keinen gemeinsamen Zustand teilen.
framer-motion wird dabei nur einmal geladen, auch wenn zehn Inseln es nutzen. Der Bundler erkennt die gemeinsame Abhängigkeit.







