Zum Inhalt springen

Astro Integrations-API

Astro-Integrationen fügen deinem Projekt neue Funktionen und Verhaltensweisen mit nur wenigen Zeilen Code hinzu.

Diese Referenzseite ist für alle, die ihre eigene Integration schreiben. Wenn du wissen willst, wie du eine Integration in deinem Projekt verwenden kannst, schau dir stattdessen unsere Anleitung Integrationen nutzen an.

Beispiele

Die offiziellen Astro-Integrationen können dir als Referenz dienen, wenn du deine eigenen Integrationen erstellen willst.

API-Kurzreferenz

interface AstroIntegration {
name: string;
hooks: {
'astro:config:setup'?: (options: {
config: AstroConfig;
command: 'dev' | 'build';
isRestart: boolean;
updateConfig: (newConfig: Record<string, any>) => void;
addRenderer: (renderer: AstroRenderer) => void;
addWatchFile: (path: URL | string) => void;
injectScript: (stage: InjectedScriptStage, content: string) => void;
injectRoute: ({ pattern: string, entrypoint: string }) => void;
}) => void;
'astro:config:done'?: (options: { config: AstroConfig }) => void | Promise<void>;
'astro:server:setup'?: (options: { server: vite.ViteDevServer }) => void | Promise<void>;
'astro:server:start'?: (options: { address: AddressInfo }) => void | Promise<void>;
'astro:server:done'?: () => void | Promise<void>;
'astro:build:start'?: () => void | Promise<void>;
'astro:build:setup'?: (options: {
vite: ViteConfigWithSSR;
pages: Map<string, PageBuildData>;
target: 'client' | 'server';
}) => void | Promise<void>;
'astro:build:generated'?: (options: { dir: URL }) => void | Promise<void>;
'astro:build:ssr'?: (options: { manifest: SerializedSSRManifest }) => void | Promise<void>;
'astro:build:done'?: (options: { dir: URL; routes: RouteData[] }) => void | Promise<void>;
};
}

Hooks

astro:config:setup

Nächster Hook: astro:config:done

Wann: Bei der Initialisierung, bevor entweder die Vite oder die Astro config (EN) verarbeitet wurden.

Warum: Um die Projektkonfiguration zu erweitern. Dazu gehört das Aktualisieren der Astro config (EN), das Anwenden von Vite plugins, das Hinzufügen von Komponenten-Renderern und das Einfügen von Skripten in die Seite.

'astro:config:setup'?: (options: {
config: AstroConfig;
command: 'dev' | 'build';
isRestart: boolean;
updateConfig: (newConfig: Record<string, any>) => void;
addRenderer: (renderer: AstroRenderer) => void;
addWatchFile: (path: URL | string) => void;
injectScript: (stage: InjectedScriptStage, content: string) => void;
injectRoute: ({ pattern: string, entrypoint: string }) => void;
}) => void;

config-Option

Typ: AstroConfig

Eine schreibgeschützte Kopie der vom Benutzer bereitgestellten Astro-Konfiguration (EN). Sie wird aufgelöst, bevor alle anderen Integrationen ausgeführt wurden. Wenn du eine Kopie der Konfiguration brauchst, nachdem alle Integrationen ihre Aktualisierungen abgeschlossen haben, siehe den Hook astro:config:done.

command-Option

Typ: 'dev' / 'build'

  • dev - Projekt wird mit astro dev oder astro preview ausgeführt
  • build - Projekt wird mit astro build ausgeführt

isRestart-Option

Typ: boolean

false, wenn der Dev-Server startet, True, wenn ein Reload ausgelöst wird. Nützlich, um zu erkennen, wenn diese Funktion mehr als einmal aufgerufen wird.

updateConfig-Option

Typ: (newConfig: Record<string, any>) => void;

Eine Callback-Funktion zum Aktualisieren der vom Benutzer bereitgestellten Astro-Konfiguration (EN). Jede Konfiguration, die du bereitstellst, wird mit der Benutzerkonfiguration und anderen Aktualisierungen der Integrationskonfiguration zusammengeführt, du kannst also auch Schlüssel weglassen!

Angenommen, du musst ein Vite-Plugin für das Projekt des Benutzers bereitstellen:

import bananaCSS from '@vitejs/official-banana-css-plugin';
export default {
name: 'banana-css-integration',
hooks: {
'astro:config:setup': ({ updateConfig }) => {
updateConfig({
vite: {
plugins: [bananaCSS()],
}
})
}
}
}

addRenderer-Option

Type: (renderer: AstroRenderer ) => void; Examples: lit, svelte, react, preact, vue, solid

Eine Callback-Funktion, um einen Komponenten-Framework-Renderer hinzuzufügen (z.B. React, Vue, Svelte, etc.). In den Beispielen und der Typdefinition oben findest du weitere Optionen, aber hier sind die 2 wichtigsten, die du beachten solltest:

  • clientEntrypoint - Pfad zu einer Datei, die auf dem Client ausgeführt wird, wenn deine Komponente verwendet wird. Dies ist vor allem für das Rendern oder die Hydratisierung deiner Komponente mit JS wichtig.
  • serverEntrypoint - Pfad zu einer Datei, die bei serverseitigen Anfragen oder statischen Builds ausgeführt wird, wenn deine Komponente verwendet wird. Diese sollten die Komponenten in statisches Markup umwandeln, ggf. mit Hooks für die Hydratisierung. Der React-Callback renderToString ist ein klassisches Beispiel.

addWatchFile-Option

Typ: URL | string

Wenn deine Integration von einer Konfigurationsdatei abhängt, die Vite nicht überwacht und/oder einen kompletten Neustart des Dev-Servers benötigt, um wirksam zu werden, füge sie mit addWatchFile hinzu. Immer wenn sich diese Datei ändert, wird der Astro Dev Server neu gestartet (du kannst mit isRestart überprüfen, wann ein Neustart erfolgt).

Example usage:

// Muss ein absoluter Pfad sein!
addWatchFile('/home/user/.../my-config.json');
addWatchFile(new URL('./tailwind.config.js', config.root));

injectRoute-Option

Type: ({ pattern: string, entrypoint: string }) => void;

Eine Callback-Funktion, um Routen in ein Astro-Projekt zu injizieren. Injizierte Routen können .astro-Seiten oder .js und .ts-Routenhandler sein.

injectRoute nimmt ein Objekt mit einem Pattern und einem EntryPoint.

  • pattern - wo die Route im Browser ausgegeben werden soll, z.B. /foo/bar. Ein Muster kann Astros Dateipfad-Syntax verwenden, um dynamische Routen zu bezeichnen, z.B. /foo/[bar] oder /foo/[...bar]. Beachte, dass eine Dateierweiterung nicht im Pattern benötigt wird.
  • entrypoint - ein reiner Modulbezeichner, der auf die .astro-Seite oder den .js/.ts-Routenhandler zeigt, der die im pattern angegebene Route bearbeitet.

Beispiel für die Verwendung:

injectRoute({
pattern: '/foo/[dynamic]',
entrypoint: 'foo/dynamic-page.astro'
});

injectScript-Option

Typ: (stage: InjectedScriptStage, content: string) => void;

Eine Callback-Funktion, die einen String mit JavaScript-Inhalt auf jeder Seite einfügt.

Die stage gibt an, wie dieses Skript (der content) eingefügt werden soll. Einige Stufen erlauben das Einfügen von Skripten ohne Änderungen, während andere eine Optimierung während des Vite-Bündelungsschritts ermöglichen:

  • "head-inline": Eingefügt in ein Skript-Tag im <head> jeder Seite. Nicht von Vite optimiert oder aufgelöst.

  • before-hydration: Wird clientseitig importiert, bevor das Hydrations-Skript läuft. Optimiert und aufgelöst von Vite.

  • "page": Ähnlich wie head-inline, mit dem Unterschied, dass das eingefügte Snippet von Vite verarbeitet und mit allen anderen <script>-Tags gebündelt wird, die innerhalb von Astro-Komponenten auf der Seite definiert sind. Das Skript wird mit einem <script type="module"> in die endgültige Seitenausgabe geladen und von Vite optimiert und aufgelöst.

  • "page-ssr": Wird als separates Modul in das Frontmatter jeder Astro-Seitenkomponente importiert. Da in dieser Phase dein Skript importiert wird, ist das globale Astro-Objekt nicht verfügbar und dein Skript wird nur einmal ausgeführt, wenn der Import zum ersten Mal ausgewertet wird.

    Die Hauptanwendung für die page-ssr-Stufe ist das Einfügen eines CSS-imports in jede Seite, die von Vite optimiert und aufgelöst werden soll:

    injectScript('page-ssr', 'import "global-styles.css";');

astro:config:done

Vorheriger Hook: astro:config:setup

Nächster Hook: astro:server:setup, wenn es im “dev”-Modus läuft, oder astro:build:start während der Produktions-Builds

Wann: Nachdem die Astro-Konfiguration aufgelöst wurde und andere Integrationen ihre astro:config:setup-Hooks ausgeführt haben.

Warum: Um die endgültige Konfiguration zur Verwendung in anderen Hooks abzurufen.

'astro:config:done'?: (options: { config: AstroConfig }) => void | Promise<void>;

config-Option

Typ: AstroConfig

Eine schreibgeschützte Kopie der vom Benutzer bereitgestellten Astro-Konfiguration (EN). Dies wird aufgelöst, nachdem andere Integrationen gelaufen sind.

astro:server:setup

Vorheriger Hook: astro:config:done

Nächster Hook: astro:server:start

Wann: Kurz nachdem der Vite-Server im “dev”-Modus erstellt wurde, aber bevor das Ereignis listen() ausgelöst wird. Siehe Vites createServer API für weitere Informationen.

Warum: Um die Vite-Serveroptionen und die Middleware zu aktualisieren.

'astro:server:setup'?: (options: { server: vite.ViteDevServer }) => void | Promise<void>;

server-Option

Typ: ViteDevServer

Eine veränderbare Instanz des Vite-Servers, die im “dev”-Modus verwendet wird. Dies wird zum Beispiel von unserer Partytown-Integration (EN) verwendet, um den Partytown-Server als Middleware zu injizieren:

export default {
name: 'partytown',
hooks: {
'astro:server:setup': ({ server }) => {
server.middlewares.use(
function middleware(req, res, next) {
// Anfragen bearbeiten
}
);
}
}
}

astro:server:start

Vorheriger Hook: astro:server:setup

Nächster Hook: astro:server:done

Wann: Kurz nachdem das Ereignis Listen() des Servers ausgelöst wurde.

Warum: Um Netzwerkanfragen an der angegebenen Adresse abzufangen. Wenn du diese Adresse für Middleware nutzen willst, solltest du stattdessen astro:server:setup verwenden.

'astro:server:start'?: (options: { address: AddressInfo }) => void | Promise<void>;

address-Option

Typ: AddressInfo

Die Adresse, Familie und Portnummer, die vom NodeJS-Net-Modul bereitgestellt wird.

astro:server:done

Vorheriger Hook: astro:server:start

Wann: Kurz nachdem der Dev-Server beendet wurde.

Warum: Um alle Bereinigungsereignisse auszuführen, die du während der astro:server:setup oder astro:server:start Hooks auslösen willst.

'astro:server:done'?: () => void | Promise<void>;

astro:build:start

Vorheriger Hook: astro:config:done

Nächster Hook: astro:build:setup

Wann: Nach dem Ereignis astro:config:done, aber bevor der Produktions-Build beginnt.

Warum: Um alle globalen Objekte oder Clients einzurichten, die während eines Produktions-Builds benötigt werden. Dies kann auch die Build-Konfigurationsoptionen in der Adapter-API (EN) erweitern.

'astro:build:start'?: () => void | Promise<void>;

astro:build:setup

Vorheriger Hook: astro:build:start

Nächster Hook: astro:build:ssr

Wenn: Nach dem astro:build:start-Hook, läuft unmittelbar vor dem Build.

Warum: Zu diesem Zeitpunkt ist die Vite-Konfiguration für den Build vollständig erstellt worden. Das kann zum Beispiel nützlich sein, um einige Standardeinstellungen zu überschreiben. Wenn du dir nicht sicher bist, ob du diesen Hook oder astro:build:start verwenden sollst, verwende stattdessen astro:build:start.

'astro:build:setup'?: (options: {
vite: ViteConfigWithSSR;
pages: Map<string, PageBuildData>;
target: 'client' | 'server';
}) => void | Promise<void>;

astro:build:generated

Vorheriger Hook: astro:build:setup

Wann: Nachdem ein statischer Produktions-Build die Erstellung von Routen und Assets abgeschlossen hat.

Warum: Um auf generierte Routen und Assets zuzugreifen, bevor Build-Artefakte bereinigt werden. Dies ist ein sehr seltener Anwendungsfall. Wir empfehlen die Verwendung von astro:build:done, es sei denn, du brauchst den Zugriff auf die erzeugten Dateien vor der Bereinigung wirklich.

'astro:build:generated'?: (options: { dir: URL }) => void | Promise<void>;

astro:build:ssr

Vorheriger Hook: astro:build:setup

Wann: Nachdem ein SSR-Produktions-Build abgeschlossen wurde.

Warum: Um Zugriff auf das SSR-Manifest zu erhalten. Dies ist nützlich, wenn du eigene SSR-Builds in Plugins oder Integrationen erstellst.

'astro:build:ssr'?: (options: { manifest: SerializedSSRManifest }) => void | Promise<void>;

astro:build:done

Vorheriger Hook: astro:build:ssr

Wann: Nachdem ein Produktions-Build (SSG oder SSR) abgeschlossen wurde.

Warum: Um auf generierte Routen und Assets für die Erweiterung zuzugreifen (z.B. um Inhalte in das generierte /assets Verzeichnis zu kopieren). Wenn du vorhast, die generierten Assets umzuwandeln, empfehlen wir, stattdessen die Vite Plugin-API und die Konfiguration über astro:config:setup zu nutzen.

'astro:build:done'?: (options: { dir: URL; routes: RouteData[] }) => void | Promise<void>;

dir-Option

Typ: URL

Ein URL-Pfad zum Verzeichnis der Build-Ausgabe. Wenn du einen gültigen absoluten Pfad benötigst, solltest du das in Node integrierte Tool fileURLToPath verwenden.

import { writeFile } from 'node:fs/promises';
import { fileURLToPath } from 'node:url';
export default function myIntegration() {
return {
hooks: {
'astro:build:done': async ({ dir }) => {
const metadata = await getIntegrationMetadata();
// Verwende fileURLToPath, um einen gültigen, plattformübergreifenden absoluten Pfadstring zu erhalten
const outFile = fileURLToPath(new URL('./my-integration.json', dir));
await writeFile(outFile, JSON.stringify(metadata));
}
}
}
}

routes-Option

Typ: RouteData[]

Eine Liste aller generierten Routen mit den dazugehörigen Metadaten. Diese Liste ist leer, wenn du einen SSR-Adapter verwendest!

Du kannst unten auf den kompletten Typ RouteData verweisen, aber die häufigsten Eigenschaften sind:

  • component - den Pfad der Eingabedatei relativ zum Stammverzeichnis des Projekts
  • pathname - die URL der Ausgabedatei (undefiniert für Routen mit den Parametern [dynamic] und [...spread])
RouteData Typ-Referenz
interface RouteData {
/** Ob eine gegebene Route eine HTML-Seite oder ein Nicht-HTML-Endpunkt ist */
type: 'page' | 'endpoint';
/** URL der Quellkomponente */
component: string;
/**
* Ausgabe-URL-Pfadname, unter dem diese Route erreichbar werden soll
* hinweis: wird für [dynamic] und [...spread]-Routen undefiniert sein
*/
pathname?: string;
/**
* regex für den Abgleich einer Eingabe-URL mit einer angeforderten Route
* bsp. "[fruit]/about.astro" wird dieses Pattern erzeugen: /^\/([^/]+?)\/about\/?$/
* wenn pattern.test("banana/about") "true" ist
*/
pattern: RegExp;
/**
* Dynamische und verteilte Routenparameter
* bsp. "/pages/[lang]/[..slug].astro" gibt die Parameter ['lang', '...slug'] aus
*/
params: string[];
/**
* Ähnlich wie das Feld "params", aber mit mehr zugehörigen Metadaten
* bsp. "/seiten/[lang]/index.astro" wird die Segmente ausgeben
* [[ { content: 'lang', dynamic: true, spread: false } ]]
*/
segments: { content: string; dynamic: boolean; spread: boolean; }[][];
/**
* Funktion zum Rendering einer Komponente an Ort und Stelle aus einem Satz von Eingabedaten.
* Dies ist in der Regel für den internen Gebrauch, benutze es mit Vorsicht!
*/
generate: (data?: any) => string;
}

Installation mit astro add zulassen

Mit dem Befehl astro add (EN) kannst du deinem Projekt ganz einfach Integrationen und Adapter hinzufügen. Wenn du möchtest, dass deine Integration mit diesem Tool installiert werden kann, füge astro-integration in das Feld keywords in deiner package.json ein:

{
"name": "example",
"keywords": ["astro-integration"],
}

Sobald du deine Integration bei npm veröffentlicht hast, wird durch die Ausführung von astro add example dein Paket mit allen in der package.json angegebenen Abhängigkeiten installiert. Dadurch wird deine Integration auch auf die astro.config des Benutzers angewendet:

astro.config.mjs
import { defineConfig } from 'astro/config';
import example from 'example';
export default defineConfig({
integrations: [example()],
})

Integrations-Reihenfolge

Alle Integrationen werden in der Reihenfolge ausgeführt, in der sie konfiguriert wurden. Zum Beispiel wird für das Array [react(), svelte()] in der astro.config.* eines Nutzers, react vor svelte ausgeführt.

Deine Integration sollte idealerweise in beliebiger Reihenfolge ausgeführt werden. Wenn das nicht möglich ist, empfehlen wir zu dokumentieren, dass deine Integration an erster oder letzter Stelle im Konfigurationsfeld Integrationen deines Benutzers stehen muss.

Integrationen zu Voreinstellungen zusammenfassen

Eine Integration kann auch als eine Sammlung von mehreren kleineren Integrationen geschrieben werden. Wir nennen diese Sammlungen Presets. Anstatt eine Factory-Funktion zu erstellen, die ein einzelnes Integrationsobjekt zurückgibt, liefert ein Preset ein array von Integrationsobjekten. Dies ist nützlich, um komplexe Funktionen aus mehreren Integrationen zu erstellen.

integrations: [
// Beispiel: examplePreset() gibt zurück: [integrationOne, integrationTwo, ...etc]
examplePreset()
]