Zum Hauptinhalt springen

Astro für Einsteiger

Ein umfassender Leitfaden zum Erstellen Ihrer ersten Website mit Astro, einschließlich Projekteinrichtung, Komponenten und Bereitstellung.

Sarah Chen Sarah Chen
7 Min. Lesezeit
Illustration: eine statische Seite mit drei hervorgehobenen interaktiven Islands

Astro hat sich schnell zu einem der beliebtesten statischen Website-Generatoren entwickelt, und das aus gutem Grund. Die Island-Architektur rendert statische Inhalte als HTML, während interaktive Funktionen dort, wo sie gebraucht werden, gezielt clientseitiges JavaScript nutzen können.

Dieser Leitfaden führt Sie durch die Bereiche von Astro, mit denen Sie in Ihrer ersten Woche arbeiten werden: Projekteinrichtung, Komponenten, Islands, Content Collections, Routing und Bereitstellung. Er setzt voraus, dass Sie mit HTML, etwas TypeScript und der Kommandozeile vertraut sind.

Ihr erstes Projekt einrichten

Der Einstieg in Astro ist unkompliziert. Öffnen Sie Ihr Terminal und führen Sie den Erstellungsbefehl aus:

npm create astro@latest

Der Einrichtungsassistent führt Sie durch die Auswahl einer Vorlage, die Installation der Abhängigkeiten und die Konfiguration von TypeScript. Für die meisten Projekte ist die Vorlage „Blog“ ein hervorragender Ausgangspunkt, da Content Collections dort bereits konfiguriert sind.

Sobald der Assistent fertig ist, starten Sie den Entwicklungsserver:

cd my-site
npm run dev

Die Website läuft dann unter http://localhost:4321 mit Hot Module Reloading. Die Projektstruktur ist überschaubar und es lohnt sich, sie früh kennenzulernen:

  • src/pages/ enthält dateibasierte Routen. Aus src/pages/about.astro wird /about.
  • src/components/ enthält wiederverwendbare Komponenten. Astro behandelt diesen Ordner nicht gesondert; es handelt sich um eine Konvention.
  • src/layouts/ enthält Seitengerüste, ebenfalls per Konvention.
  • public/ enthält Dateien, die unverändert in die Ausgabe kopiert werden, etwa favicon.svg oder robots.txt.
  • astro.config.mjs enthält Integrationen, Adapter und Build-Optionen.

Astro-Komponenten verstehen

Astro-Komponenten verwenden die Dateierweiterung .astro und kombinieren HTML-ähnliche Syntax mit einem Frontmatter-Skriptbereich. Im Gegensatz zu React- oder Vue-Komponenten rendern Astro-Komponenten zur Build-Zeit zu statischem HTML, sofern Sie nicht ausdrücklich clientseitige Hydration aktivieren.

Das Frontmatter einer Komponente läuft zur Build-Zeit auf dem Server. Sie haben dort Zugriff auf Dateiimporte, Datenabrufe und Hilfsfunktionen, ohne dass diese Logik an den Browser ausgeliefert wird.

---
interface Props {
  title: string;
  href?: string;
}

const { title, href = "/" } = Astro.props;
---

<article class="card">
  <h2><a href={href}>{title}</a></h2>
  <slot />
</article>

<style>
  .card {
    padding: 1.5rem;
    border-radius: 0.75rem;
  }
</style>

An diesem Beispiel fallen einige Dinge auf:

  • Props sind typisiert, und zwar mit einem einfachen Props-Interface. Editoren und astro check erkennen es ohne zusätzliche Konfiguration.
  • Slots funktionieren wie bei Web Components. Ein Standard-<slot /> nimmt Kindelemente auf, und benannte Slots (<slot name="footer" />) nehmen Elemente auf, die mit slot="footer" gekennzeichnet sind.
  • Styles sind standardmäßig gekapselt. Die obige .card-Regel gilt nur für diese Komponente. Verwenden Sie <style is:global>, wenn Sie tatsächlich eine globale Regel benötigen.

Wenn Sie JSX kennen, besteht die wichtigste Umstellung darin, dass es kein erneutes Rendern gibt. Das Template läuft einmal pro Anfrage oder Build, erzeugt HTML und ist damit fertig.

Islands und Client-Direktiven

Statisches HTML ist der Standard, doch früher oder später brauchen Sie etwas Interaktives: ein Suchfeld, ein Diagramm, einen Warenkorb. Astro ermöglicht es Ihnen, Komponenten aus React, Preact, Svelte, Vue oder Solid einzubinden, nachdem Sie die passende Integration hinzugefügt haben:

npx astro add react

Eine Framework-Komponente, die ohne Direktive gerendert wird, gibt weiterhin nur HTML aus. Um ihr JavaScript auszuliefern und sie zu hydrieren, fügen Sie eine client:*-Direktive hinzu:

---
import Counter from "../components/Counter.tsx";
import Chart from "../components/Chart.tsx";
---

<Counter client:load />
<Chart client:visible />

Wählen Sie die Direktive danach aus, wie dringend die Interaktion ist:

  • client:load hydriert sofort. Verwenden Sie sie für Bedienelemente im sichtbaren Bereich, die Nutzer direkt benötigen.
  • client:idle wartet, bis der Browser im Leerlauf ist. Gut geeignet für Widgets mit niedrigerer Priorität.
  • client:visible wartet, bis die Komponente in den sichtbaren Bereich scrollt. Ideal für Diagramme und Einbettungen weiter unten auf der Seite.
  • client:media="(max-width: 768px)" hydriert nur, wenn eine Media Query zutrifft, etwa bei einem Menü nur für Mobilgeräte.
  • client:only="react" überspringt das serverseitige Rendern vollständig, für Komponenten, die auf Browser-APIs angewiesen sind.

Jede Island hydriert unabhängig, sodass ein langsames Widget am Seitenende den Rest der Seite nicht blockiert. Für viele Interaktionen brauchen Sie überhaupt kein Framework: Ein <script>-Tag in einer .astro-Komponente wird von Astro gebündelt und dedupliziert, was für Umschalter, Menüs und Kopier-Buttons oft völlig ausreicht.

Content Collections

Eines der herausragendsten Merkmale von Astro sind Content Collections. Sie bieten typsicheren Zugriff auf Ihre Markdown- und MDX-Inhalte mit Schemavalidierung. Definieren Sie Ihre Inhaltsstruktur einmal, und Astro stellt sicher, dass jeder Inhalt Ihrem Schema entspricht.

Collections werden in src/content.config.ts definiert. Seit Astro 5 verwendet jede Collection einen Loader, der Astro mitteilt, woher die Einträge stammen. Der eingebaute glob()-Loader liest Dateien von der Festplatte:

import { defineCollection } from "astro:content";
import { glob } from "astro/loaders";
import { z } from "astro/zod";

const blog = defineCollection({
  loader: glob({ pattern: "**/*.{md,mdx}", base: "./src/content/blog" }),
  schema: z.object({
    title: z.string(),
    description: z.string(),
    publishDate: z.coerce.date(),
    tags: z.array(z.string()).default([]),
    draft: z.boolean().default(false),
  }),
});

export const collections = { blog };

Fehlt einem Beitrag der Titel oder ist ein Datum fehlerhaft, schlägt der Build mit einer Meldung fehl, die auf die betreffende Datei verweist. Genau das wünscht man sich im Team: Inhaltsfehler zeigen sich in der Entwicklung, nicht in der Produktion.

Eine Collection abzufragen ist ein einziger Funktionsaufruf, und die Ergebnisse sind vollständig typisiert:

---
import { getCollection } from "astro:content";

const posts = (await getCollection("blog", ({ data }) => !data.draft))
  .sort((a, b) => b.data.publishDate.valueOf() - a.data.publishDate.valueOf());
---

<ul>
  {posts.map((post) => (
    <li><a href={`/blog/${post.id}/`}>{post.data.title}</a></li>
  ))}
</ul>

Loader sind nicht auf lokale Dateien beschränkt. Der file()-Loader liest eine einzelne JSON- oder YAML-Datei, und Sie können eigene Loader schreiben, die Inhalte aus einem Headless CMS oder einer API beziehen, bei gleicher Schemavalidierung und gleicher Abfrageschnittstelle.

Routing und dynamische Seiten

Jede Datei in src/pages/ ist eine Route. Für Seiten, die aus Daten erzeugt werden, etwa eine Seite pro Blogbeitrag, verwenden Sie einen Dateinamen in eckigen Klammern und exportieren getStaticPaths():

---
// src/pages/blog/[id].astro
import { getCollection, render } from "astro:content";

export async function getStaticPaths() {
  const posts = await getCollection("blog");
  return posts.map((post) => ({ params: { id: post.id }, props: { post } }));
}

const { post } = Astro.props;
const { Content, headings } = await render(post);
---

<h1>{post.data.title}</h1>
<Content />

render() liefert außerdem die Überschriften des Beitrags, was praktisch ist, um ein Inhaltsverzeichnis zu erstellen, ohne selbst etwas parsen zu müssen.

Bereitstellung

Astro unterstützt von Haus aus mehrere Bereitstellungsziele. Für Vercel, Netlify, Cloudflare Pages und Node-Server gibt es jeweils einen offiziellen Adapter, den npx astro add installiert und konfiguriert. Für statische Websites benötigt die eingebaute Ausgabe keine zusätzliche Konfiguration.

npm run build schreibt eine statische Website nach dist/, die jeder statische Host oder jedes CDN ausliefern kann. Wenn Sie Code benötigen, der pro Anfrage läuft, etwa für Formularverarbeitung, Authentifizierung oder personalisierte Seiten, fügen Sie einen Adapter für Ihren Host hinzu:

npx astro add node

Mit installiertem Adapter können Sie die meisten Seiten weiterhin vorrendern und einzelne Routen mit export const prerender = false davon ausnehmen. Setzen Sie vor der Bereitstellung site in astro.config.mjs, damit kanonische URLs, Sitemaps und RSS-Feeds auf Ihre tatsächliche Domain verweisen.

Wie es weitergeht

Sobald Ihnen die Grundlagen vertraut sind, lohnt es sich, einige Funktionen etwa in dieser Reihenfolge zu erkunden:

  1. Bilder. Die <Image />-Komponente aus astro:assets übernimmt Größenanpassung, moderne Formate sowie Breiten- und Höhenattribute, die Layoutverschiebungen verhindern.
  2. View Transitions. Wenn Sie die <ClientRouter />-Komponente in Ihr Layout einfügen, erhalten Sie mit sehr wenig Code animierte clientseitige Navigation.
  3. Actions. Astro Actions bieten typsichere Serverfunktionen mit Eingabevalidierung und eignen sich ideal für Kontaktformulare und Newsletter.
  4. Server Islands. Mit der Direktive server:defer kann eine überwiegend statische Seite ein personalisiertes Fragment, etwa ein Benutzermenü, bei Bedarf rendern.

Fangen Sie klein an: ein Layout, eine Collection, ein paar Seiten. Astro belohnt diesen Ansatz, denn jede Seite, die Sie hinzufügen, bleibt so schnell wie die erste.

Diesen Artikel teilen
astro frontend performance