Astro und Alpine gehen in der Praxis gut zusammen.Dmytro Vietrov | shutterstock.com Softwareentwickler, die ihren Job gerne machen, sind immer offen für funktionale, qualitativ hochwertige Tools, die die Developer Experience bereichern können. Das trifft sowohl auf Astro als auch auf Alpine zu. Während das erstgenannte Framework eine stabile, Server-seitige Plattform bietet, um Web-Applikationen an den Start zu bringen, ist zweitgenanntes eine bevorzugte Option für Frontend-Minimalisten. Kombiniert man die beiden Rahmenwerke, ist das Ergebnis ein schlanker, aber sehr vielseitiger Stack, der einige der besten Features von Astro und Alpine zusammenbringt. In diesem Tutorial entwickeln wir eine Beispiel-Webanwendung, die dieses Zusammenspiel demonstriert. Der Astro-Alpine-Stack im Überblick Astro ist in erster Linie als Meta-Framework bekannt, um Reactive-Frameworks wie React und Svelte zu integrieren. Bei Alpine handelt es sich zwar ebenfalls um ein reaktives Framework, dieses ist aber so schlank designt, dass es in Kombination mit Astro anders funktioniert – in erster Linie, weil es einige Integrations-Formalitäten vermeidet. So bietet Astro bereits eine ganze Reihe von Funktionen, um Server-seitige Komponenten zu definieren. Die klare Syntax von Alpine erleichtert es schließlich, verschiedene Teile einer Anwendung um Interaktivität und API-Calls zu ergänzen. Weil Astro standardmäßig auch ein offizielles Alpine-Plugin enthält, funktioniert die Kombination der beiden Frameworks quasi nahtlos. Lediglich wenn es darum geht, eine Alpine-Komponente mit SSG (Static Site Generation) -Daten aus Astro zu steuern, sind ein paar kleinere Kniffe notwendig. Im Großen und Ganzen ist Astro plus Alpine aber eine sehr gute Idee, wenn Sie etwas entwickeln möchten, das größtenteils auf Astros SSG läuft und für raffiniertere Interaktionen auf Alpine zurückgreift. Der Hauptteil dieses Artikels gliedert sich in drei Entwicklungsebenen – die in aufsteigender Reihenfolge stärker auf Alpine basieren: Ebene 1 dreht sich um reines SSG mit simpler, Client-seitiger Erweiterung. Ebene 2 beschäftigt sich mit dynamischem Server-Side Rendering (SSR) inklusive Client-seitiger Erweiterung. Ebene 3 konzentriert sich auf Client-seitiges Rendering mit API-Aufrufen. Die Beispielanwendung und ihr Layout Um die einzelnen Ebenen und ihre Unterschiede deutlicher herauszuarbeiten, erstellen wir nachfolgend eine fiktive Webanwendung namens “Coast Mountain Adventures”. Die App soll aus drei verschiedenen Seiten bestehen, die die eben dargelegten Entwicklungsebenen repräsentieren: Auf Ebene 1 erstellen wir eine “About”-Seite, die eine einfache Akkordeonansicht mit statischen Inhalten beherbergt. Auf Ebene 2 erstellen wir eine “Gear Shops”-Seite, die lokale Outdoor-Einzelhandelsgeschäfte auflistet. Diese List wird mit Astro generiert und von Alpine gefiltert. Auf Ebene 3 erstellen wir eine “My Adventures”-Seite. Diese nimmt über eine API eine Benutzer-ID entgegen und gibt eine JSON-Antwort mit den Daten des Benutzers zurück, die von Alpine auf dem Client gerendert werden. Um loslegen zu können, müssen Sie zunächst Astro installieren, eine neue Anwendung damit erstellen und die Integration von Alpine starten (für ein einfaches responsives Styling haben wir zudem das Tailwind-Plugin installiert – CSS wird in diesem Tutorial allerdings nicht thematisiert). $ npm create astro@latest — –template minimal $ npx astro add alpinejs $ npx astro add tailwind Unser Framing-Material (das Layout) ist simpel und besteht lediglich aus einem Titel und ein paar Links. Astro fasst diese zusammen und liefert sie ohne JavaScript aus: — import ‘./src/styles/global.css’; — Astro Alpine Coast Mountain Adventures My Adventures Gear Shops About Beachten Sie in diesem Code-Snippet das Element ;: Hier wird Astro die Seiten ablegen, die dieses Layout verwenden (weitere Informationen zu Astro-Layouts finden Sie in der Dokumentation). Astro übernimmt auch das Routing der URLs an die richtigen Dateien auf der Festplatte im Verzeichnis /src/pages. Ebene 1: Die “About”-Seite Unsere “About”-Seite besteht aus drei Abschnitten: einer Haupt- und zwei Untersektionen. Für dieses Tutorial erstellen wir die beiden Unterabschnitte als Akkordeon-Panels, deren Inhalte per Klick ein- oder ausgeblendet werden. — import Layout from ‘../layouts/Layout.astro’; — About Us We are a consortium of outdoor enthusiasts and locally owned gear shops and exchanges, dedicated to the truth that when nature and people come together, Good Things happen. Our Mission {/* Add the icon span */} ↓ {/* Down arrow character */} To connect people with nature and provide access to quality outdoor gear, experiences and curated resources. Our Values ↓ Community Sustainability Adventure Abgesehen vom Astro-Layout enthält diese Ebene ansonsten nichts Astro-Spezifisches. Es handelt sich lediglich um HTML mit einigen wenigen Alpine-Direktiven, nämlich: x-data (definiert das Datenobjekt für die Alpine-Komponente), x-on:click (definiert einen Onclick-Handler), sowie x-show (blendet das Element konditional ein oder aus). Das ist auch schon alles, was wir für unsere Akkordeons benötigen – plus ein wenig CSS für die Pfeilsymbole. So sieht unsere Seite momentan aus: Matthew Tyson Ebene 2: Die “Gear Shop”-Seite Für unsere “Gear Shop”-Seite möchten wir einen Teil der im Backend verfügbaren Daten so rendern, dass der Client sie filtern kann. Deshalb rendern wir die Daten mit Astro Server-seitig und erstellen eine Alpine-Komponente, die diese verarbeiten kann und dynamische UI-Interaktionen ermöglicht. Doch eins nach dem anderen – zunächst erstellen wir die Seite selbst: — // src/pages/gear-shops.astro import Layout from ‘../layouts/Layout.astro’; import GearShopList from ‘../components/GearShopList.astro’; const gearShops = [ { name: “Adventure Outfitters”, category: “Hiking” }, { name: “Peak Performance Gear”, category: “Climbing” }, { name: “River Rat Rentals”, category: “Kayaking” }, { name: “The Trailhead”, category: “Hiking” }, { name: “Vertical Ventures”, category: “Climbing” } ]; — Local Gear Shops Die Daten befinden sich in der Variablen gearShops. Sie könnten aus einer Datenbank, einer externen API, einem lokalen Dateisystem oder den integrierten Content Collections von Astro stammen. Der Punkt ist: Sie werden auf dem Server produziert. Der Trick besteht nun darin, sie als Live-JSON auf dem Client verfügbar zu machen – wo Alpine sie nutzen kann. Dazu müssen die Daten zunächst auf der shops-Property der GearShopList-Komponente in String-Form gebracht werden. Dadurch kann Astro sie serialisieren, wenn es die Ansicht an den Browser sendet (im Wesentlichen wird JSON.stringify(gearShops) in das HTML-Dokument eingefügt). Ein Blick auf GearShopList: — const { shops, initialCount } = Astro.props; // Receive the ‘shops’ prop if (!shops) { throw new Error(‘GearShopList component requires a “shops” prop that is an array.’); } — All Hiking Climbing () Dieser Code ist relativ selbsterklärend, mit Ausnahme des x-data-Attributs . Der Zweck ist klar: Wir wollen ein JavaScript-Objekt mit einem filter– und einem shops-Feld erstellen, wobei letzteres das Live-JavaScript-Objekt enthält, das wir zuvor auf dem Server erstellt haben. Die zusätzlichen Zeichen sind nötig, um das syntaktisch zu bewerkstelligen. Der Schlüssel, um x-data zu verstehen, ist dabei die {“}-Syntax – geschweifte Klammern mit zwei Backticks –, die zu einem leeren String aufgelöst wird. Soll heißen: Das x-data-Feld ist letztendlich ein String-Literal-Objekt, das die shops-Variable als JSON interpoliert. Alpine verarbeitet all das und wandelt es in ein Live-Objekt um, um die Komponente zu steuern (die Funktionsweise dieses Anwendungsteils lässt sich auch anhand dieser Astro-Alpine-Demo-Anwendung auf GitHub nachvollziehen). Neben dem x-data-Attribut bindet x-model den Auswahlwert an die filter-Variable. Mit x-for können wir über Shops iterieren. So sieht unsere “Gear Shops”-Seite nun aus: Matthew Tyson Ebene 3: Die “Adventures”-Seite Im Fall der “Adventures”-Seite kommt schließlich Alpine zum Zug. Damit Astro nicht in Sachen SSG tätig wird, ist es an dieser Stelle nötig, seine Pre-Rendering-Funktion zu deaktivieren. — import Layout from ‘../layouts/Layout.astro’; export const prerender = false; // Important: Disable prerendering for this page — My Adventures Loading adventures… {/*… other adventure details… */} Diese Seite demonstriert die Vielseitigkeit und Performanz von Alpine: Das x-data-Attribut enthält sowohl die data-Property (adventures) als auch eine Fetching-Methode (fetchAdventures()). Wird x-init bei der Initialisierung der Komponenten aufgerufen, callt es die fetchAdventures()-Funktion, die wiederum unseren Server aufruft und adventures mit Daten befüllt. Dabei ist alles übersichtlich in einem kleinen Bereich zusammengefasst, in dem Daten, Verhalten und Ansicht logisch miteinander verknüpft sind. Anschließend verwenden wir x-if, um auf Basis von adventures.length entweder eine Loading Message oder die eigentliche Liste anzuzeigen. Die Adventures-API Zu guter Letzt benötigen wir noch einen Backend-Endpunkt, um die Adventures-JSON für diesen Call bereitzustellen: export async function GET() { const adventures = [ { id: 1, title: “Hiking Trip to Mount Hood”, date: “2024-08-15” }, { id: 2, title: “Kayaking Adventure on the Rogue River”, date: “2024-09-22” }, //… more adventures ]; return new Response(JSON.stringify(adventures), { status: 200, headers: { ‘Content-Type’: ‘application/json’ } }); } Ein Blick auf unsere “Adventures”-Seite: Matthew Tyson (fm) Sie wollen weitere interessante Beiträge zu diversen Themen aus der IT-Welt lesen? Unsere kostenlosen Newsletter liefern Ihnen alles, was IT-Profis wissen sollten – direkt in Ihre Inbox!
Web-Apps mit Astro und Alpine entwickeln
Astro und Alpine gehen in der Praxis gut zusammen.Dmytro Vietrov | shutterstock.com Softwareentwickler, die ihren Job gerne machen, sind immer offen für funktionale, qualitativ hochwertige Tools, die die Developer Experience bereichern können. Das trifft sowohl auf Astro als auch auf Alpine zu. Während das erstgenannte Framework eine stabile, Server-seitige Plattform bietet, um Web-Applikationen an den Start zu bringen, ist zweitgenanntes eine bevorzugte Option für Frontend-Minimalisten. Kombiniert man die beiden Rahmenwerke, ist das Ergebnis ein schlanker, aber sehr vielseitiger Stack, der einige der besten Features von Astro und Alpine zusammenbringt. In diesem Tutorial entwickeln wir eine Beispiel-Webanwendung, die dieses Zusammenspiel demonstriert. Der Astro-Alpine-Stack im Überblick Astro ist in erster Linie als Meta-Framework bekannt, um Reactive-Frameworks wie React und Svelte zu integrieren. Bei Alpine handelt es sich zwar ebenfalls um ein reaktives Framework, dieses ist aber so schlank designt, dass es in Kombination mit Astro anders funktioniert – in erster Linie, weil es einige Integrations-Formalitäten vermeidet. So bietet Astro bereits eine ganze Reihe von Funktionen, um Server-seitige Komponenten zu definieren. Die klare Syntax von Alpine erleichtert es schließlich, verschiedene Teile einer Anwendung um Interaktivität und API-Calls zu ergänzen. Weil Astro standardmäßig auch ein offizielles Alpine-Plugin enthält, funktioniert die Kombination der beiden Frameworks quasi nahtlos. Lediglich wenn es darum geht, eine Alpine-Komponente mit SSG (Static Site Generation) -Daten aus Astro zu steuern, sind ein paar kleinere Kniffe notwendig. Im Großen und Ganzen ist Astro plus Alpine aber eine sehr gute Idee, wenn Sie etwas entwickeln möchten, das größtenteils auf Astros SSG läuft und für raffiniertere Interaktionen auf Alpine zurückgreift. Der Hauptteil dieses Artikels gliedert sich in drei Entwicklungsebenen – die in aufsteigender Reihenfolge stärker auf Alpine basieren: Ebene 1 dreht sich um reines SSG mit simpler, Client-seitiger Erweiterung. Ebene 2 beschäftigt sich mit dynamischem Server-Side Rendering (SSR) inklusive Client-seitiger Erweiterung. Ebene 3 konzentriert sich auf Client-seitiges Rendering mit API-Aufrufen. Die Beispielanwendung und ihr Layout Um die einzelnen Ebenen und ihre Unterschiede deutlicher herauszuarbeiten, erstellen wir nachfolgend eine fiktive Webanwendung namens “Coast Mountain Adventures”. Die App soll aus drei verschiedenen Seiten bestehen, die die eben dargelegten Entwicklungsebenen repräsentieren: Auf Ebene 1 erstellen wir eine “About”-Seite, die eine einfache Akkordeonansicht mit statischen Inhalten beherbergt. Auf Ebene 2 erstellen wir eine “Gear Shops”-Seite, die lokale Outdoor-Einzelhandelsgeschäfte auflistet. Diese List wird mit Astro generiert und von Alpine gefiltert. Auf Ebene 3 erstellen wir eine “My Adventures”-Seite. Diese nimmt über eine API eine Benutzer-ID entgegen und gibt eine JSON-Antwort mit den Daten des Benutzers zurück, die von Alpine auf dem Client gerendert werden. Um loslegen zu können, müssen Sie zunächst Astro installieren, eine neue Anwendung damit erstellen und die Integration von Alpine starten (für ein einfaches responsives Styling haben wir zudem das Tailwind-Plugin installiert – CSS wird in diesem Tutorial allerdings nicht thematisiert). $ npm create astro@latest -- --template minimal $ npx astro add alpinejs $ npx astro add tailwind Unser Framing-Material (das Layout) ist simpel und besteht lediglich aus einem Titel und ein paar Links. Astro fasst diese zusammen und liefert sie ohne JavaScript aus: --- import './src/styles/global.css'; --- Astro Alpine Coast Mountain Adventures My Adventures Gear Shops About Beachten Sie in diesem Code-Snippet das Element ;: Hier wird Astro die Seiten ablegen, die dieses Layout verwenden (weitere Informationen zu Astro-Layouts finden Sie in der Dokumentation). Astro übernimmt auch das Routing der URLs an die richtigen Dateien auf der Festplatte im Verzeichnis /src/pages. Ebene 1: Die “About”-Seite Unsere “About”-Seite besteht aus drei Abschnitten: einer Haupt- und zwei Untersektionen. Für dieses Tutorial erstellen wir die beiden Unterabschnitte als Akkordeon-Panels, deren Inhalte per Klick ein- oder ausgeblendet werden. --- import Layout from '../layouts/Layout.astro'; --- About Us We are a consortium of outdoor enthusiasts and locally owned gear shops and exchanges, dedicated to the truth that when nature and people come together, Good Things happen. Our Mission {/* Add the icon span */} ↓ {/* Down arrow character */} To connect people with nature and provide access to quality outdoor gear, experiences and curated resources. Our Values ↓ Community Sustainability Adventure Abgesehen vom Astro-Layout enthält diese Ebene ansonsten nichts Astro-Spezifisches. Es handelt sich lediglich um HTML mit einigen wenigen Alpine-Direktiven, nämlich: x-data (definiert das Datenobjekt für die Alpine-Komponente), x-on:click (definiert einen Onclick-Handler), sowie x-show (blendet das Element konditional ein oder aus). Das ist auch schon alles, was wir für unsere Akkordeons benötigen – plus ein wenig CSS für die Pfeilsymbole. So sieht unsere Seite momentan aus: Matthew Tyson Ebene 2: Die “Gear Shop”-Seite Für unsere “Gear Shop”-Seite möchten wir einen Teil der im Backend verfügbaren Daten so rendern, dass der Client sie filtern kann. Deshalb rendern wir die Daten mit Astro Server-seitig und erstellen eine Alpine-Komponente, die diese verarbeiten kann und dynamische UI-Interaktionen ermöglicht. Doch eins nach dem anderen – zunächst erstellen wir die Seite selbst: --- // src/pages/gear-shops.astro import Layout from '../layouts/Layout.astro'; import GearShopList from '../components/GearShopList.astro'; const gearShops = [ { name: "Adventure Outfitters", category: "Hiking" }, { name: "Peak Performance Gear", category: "Climbing" }, { name: "River Rat Rentals", category: "Kayaking" }, { name: "The Trailhead", category: "Hiking" }, { name: "Vertical Ventures", category: "Climbing" } ]; --- Local Gear Shops Die Daten befinden sich in der Variablen gearShops. Sie könnten aus einer Datenbank, einer externen API, einem lokalen Dateisystem oder den integrierten Content Collections von Astro stammen. Der Punkt ist: Sie werden auf dem Server produziert. Der Trick besteht nun darin, sie als Live-JSON auf dem Client verfügbar zu machen – wo Alpine sie nutzen kann. Dazu müssen die Daten zunächst auf der shops-Property der GearShopList-Komponente in String-Form gebracht werden. Dadurch kann Astro sie serialisieren, wenn es die Ansicht an den Browser sendet (im Wesentlichen wird JSON.stringify(gearShops) in das HTML-Dokument eingefügt). Ein Blick auf GearShopList: --- const { shops, initialCount } = Astro.props; // Receive the 'shops' prop if (!shops) { throw new Error('GearShopList component requires a "shops" prop that is an array.'); } --- All Hiking Climbing () Dieser Code ist relativ selbsterklärend, mit Ausnahme des x-data-Attributs . Der Zweck ist klar: Wir wollen ein JavaScript-Objekt mit einem filter– und einem shops-Feld erstellen, wobei letzteres das Live-JavaScript-Objekt enthält, das wir zuvor auf dem Server erstellt haben. Die zusätzlichen Zeichen sind nötig, um das syntaktisch zu bewerkstelligen. Der Schlüssel, um x-data zu verstehen, ist dabei die {``}-Syntax – geschweifte Klammern mit zwei Backticks –, die zu einem leeren String aufgelöst wird. Soll heißen: Das x-data-Feld ist letztendlich ein String-Literal-Objekt, das die shops-Variable als JSON interpoliert. Alpine verarbeitet all das und wandelt es in ein Live-Objekt um, um die Komponente zu steuern (die Funktionsweise dieses Anwendungsteils lässt sich auch anhand dieser Astro-Alpine-Demo-Anwendung auf GitHub nachvollziehen). Neben dem x-data-Attribut bindet x-model den Auswahlwert an die filter-Variable. Mit x-for können wir über Shops iterieren. So sieht unsere “Gear Shops”-Seite nun aus: Matthew Tyson Ebene 3: Die “Adventures”-Seite Im Fall der “Adventures”-Seite kommt schließlich Alpine zum Zug. Damit Astro nicht in Sachen SSG tätig wird, ist es an dieser Stelle nötig, seine Pre-Rendering-Funktion zu deaktivieren. --- import Layout from '../layouts/Layout.astro'; export const prerender = false; // Important: Disable prerendering for this page --- My Adventures Loading adventures... {/*... other adventure details... */} Diese Seite demonstriert die Vielseitigkeit und Performanz von Alpine: Das x-data-Attribut enthält sowohl die data-Property (adventures) als auch eine Fetching-Methode (fetchAdventures()). Wird x-init bei der Initialisierung der Komponenten aufgerufen, callt es die fetchAdventures()-Funktion, die wiederum unseren Server aufruft und adventures mit Daten befüllt. Dabei ist alles übersichtlich in einem kleinen Bereich zusammengefasst, in dem Daten, Verhalten und Ansicht logisch miteinander verknüpft sind. Anschließend verwenden wir x-if, um auf Basis von adventures.length entweder eine Loading Message oder die eigentliche Liste anzuzeigen. Die Adventures-API Zu guter Letzt benötigen wir noch einen Backend-Endpunkt, um die Adventures-JSON für diesen Call bereitzustellen: export async function GET() { const adventures = [ { id: 1, title: "Hiking Trip to Mount Hood", date: "2024-08-15" }, { id: 2, title: "Kayaking Adventure on the Rogue River", date: "2024-09-22" }, //... more adventures ]; return new Response(JSON.stringify(adventures), { status: 200, headers: { 'Content-Type': 'application/json' } }); } Ein Blick auf unsere “Adventures”-Seite: Matthew Tyson (fm) Sie wollen weitere interessante Beiträge zu diversen Themen aus der IT-Welt lesen? Unsere kostenlosen Newsletter liefern Ihnen alles, was IT-Profis wissen sollten – direkt in Ihre Inbox!
Web-Apps mit Astro und Alpine entwickeln Astro und Alpine gehen in der Praxis gut zusammen.Dmytro Vietrov | shutterstock.com Softwareentwickler, die ihren Job gerne machen, sind immer offen für funktionale, qualitativ hochwertige Tools, die die Developer Experience bereichern können. Das trifft sowohl auf Astro als auch auf Alpine zu. Während das erstgenannte Framework eine stabile, Server-seitige Plattform bietet, um Web-Applikationen an den Start zu bringen, ist zweitgenanntes eine bevorzugte Option für Frontend-Minimalisten. Kombiniert man die beiden Rahmenwerke, ist das Ergebnis ein schlanker, aber sehr vielseitiger Stack, der einige der besten Features von Astro und Alpine zusammenbringt. In diesem Tutorial entwickeln wir eine Beispiel-Webanwendung, die dieses Zusammenspiel demonstriert. Der Astro-Alpine-Stack im Überblick Astro ist in erster Linie als Meta-Framework bekannt, um Reactive-Frameworks wie React und Svelte zu integrieren. Bei Alpine handelt es sich zwar ebenfalls um ein reaktives Framework, dieses ist aber so schlank designt, dass es in Kombination mit Astro anders funktioniert – in erster Linie, weil es einige Integrations-Formalitäten vermeidet. So bietet Astro bereits eine ganze Reihe von Funktionen, um Server-seitige Komponenten zu definieren. Die klare Syntax von Alpine erleichtert es schließlich, verschiedene Teile einer Anwendung um Interaktivität und API-Calls zu ergänzen. Weil Astro standardmäßig auch ein offizielles Alpine-Plugin enthält, funktioniert die Kombination der beiden Frameworks quasi nahtlos. Lediglich wenn es darum geht, eine Alpine-Komponente mit SSG (Static Site Generation) -Daten aus Astro zu steuern, sind ein paar kleinere Kniffe notwendig. Im Großen und Ganzen ist Astro plus Alpine aber eine sehr gute Idee, wenn Sie etwas entwickeln möchten, das größtenteils auf Astros SSG läuft und für raffiniertere Interaktionen auf Alpine zurückgreift. Der Hauptteil dieses Artikels gliedert sich in drei Entwicklungsebenen – die in aufsteigender Reihenfolge stärker auf Alpine basieren: Ebene 1 dreht sich um reines SSG mit simpler, Client-seitiger Erweiterung. Ebene 2 beschäftigt sich mit dynamischem Server-Side Rendering (SSR) inklusive Client-seitiger Erweiterung. Ebene 3 konzentriert sich auf Client-seitiges Rendering mit API-Aufrufen. Die Beispielanwendung und ihr Layout Um die einzelnen Ebenen und ihre Unterschiede deutlicher herauszuarbeiten, erstellen wir nachfolgend eine fiktive Webanwendung namens “Coast Mountain Adventures”. Die App soll aus drei verschiedenen Seiten bestehen, die die eben dargelegten Entwicklungsebenen repräsentieren: Auf Ebene 1 erstellen wir eine “About”-Seite, die eine einfache Akkordeonansicht mit statischen Inhalten beherbergt. Auf Ebene 2 erstellen wir eine “Gear Shops”-Seite, die lokale Outdoor-Einzelhandelsgeschäfte auflistet. Diese List wird mit Astro generiert und von Alpine gefiltert. Auf Ebene 3 erstellen wir eine “My Adventures”-Seite. Diese nimmt über eine API eine Benutzer-ID entgegen und gibt eine JSON-Antwort mit den Daten des Benutzers zurück, die von Alpine auf dem Client gerendert werden. Um loslegen zu können, müssen Sie zunächst Astro installieren, eine neue Anwendung damit erstellen und die Integration von Alpine starten (für ein einfaches responsives Styling haben wir zudem das Tailwind-Plugin installiert – CSS wird in diesem Tutorial allerdings nicht thematisiert). $ npm create astro@latest -- --template minimal $ npx astro add alpinejs $ npx astro add tailwind Unser Framing-Material (das Layout) ist simpel und besteht lediglich aus einem Titel und ein paar Links. Astro fasst diese zusammen und liefert sie ohne JavaScript aus: --- import './src/styles/global.css'; --- Astro Alpine Coast Mountain Adventures My Adventures Gear Shops About Beachten Sie in diesem Code-Snippet das Element ;: Hier wird Astro die Seiten ablegen, die dieses Layout verwenden (weitere Informationen zu Astro-Layouts finden Sie in der Dokumentation). Astro übernimmt auch das Routing der URLs an die richtigen Dateien auf der Festplatte im Verzeichnis /src/pages. Ebene 1: Die “About”-Seite Unsere “About”-Seite besteht aus drei Abschnitten: einer Haupt- und zwei Untersektionen. Für dieses Tutorial erstellen wir die beiden Unterabschnitte als Akkordeon-Panels, deren Inhalte per Klick ein- oder ausgeblendet werden. --- import Layout from '../layouts/Layout.astro'; --- About Us We are a consortium of outdoor enthusiasts and locally owned gear shops and exchanges, dedicated to the truth that when nature and people come together, Good Things happen. Our Mission {/* Add the icon span */} ↓ {/* Down arrow character */} To connect people with nature and provide access to quality outdoor gear, experiences and curated resources. Our Values ↓ Community Sustainability Adventure Abgesehen vom Astro-Layout enthält diese Ebene ansonsten nichts Astro-Spezifisches. Es handelt sich lediglich um HTML mit einigen wenigen Alpine-Direktiven, nämlich: x-data (definiert das Datenobjekt für die Alpine-Komponente), x-on:click (definiert einen Onclick-Handler), sowie x-show (blendet das Element konditional ein oder aus). Das ist auch schon alles, was wir für unsere Akkordeons benötigen – plus ein wenig CSS für die Pfeilsymbole. So sieht unsere Seite momentan aus: Matthew Tyson Ebene 2: Die “Gear Shop”-Seite Für unsere “Gear Shop”-Seite möchten wir einen Teil der im Backend verfügbaren Daten so rendern, dass der Client sie filtern kann. Deshalb rendern wir die Daten mit Astro Server-seitig und erstellen eine Alpine-Komponente, die diese verarbeiten kann und dynamische UI-Interaktionen ermöglicht. Doch eins nach dem anderen – zunächst erstellen wir die Seite selbst: --- // src/pages/gear-shops.astro import Layout from '../layouts/Layout.astro'; import GearShopList from '../components/GearShopList.astro'; const gearShops = [ { name: "Adventure Outfitters", category: "Hiking" }, { name: "Peak Performance Gear", category: "Climbing" }, { name: "River Rat Rentals", category: "Kayaking" }, { name: "The Trailhead", category: "Hiking" }, { name: "Vertical Ventures", category: "Climbing" } ]; --- Local Gear Shops Die Daten befinden sich in der Variablen gearShops. Sie könnten aus einer Datenbank, einer externen API, einem lokalen Dateisystem oder den integrierten Content Collections von Astro stammen. Der Punkt ist: Sie werden auf dem Server produziert. Der Trick besteht nun darin, sie als Live-JSON auf dem Client verfügbar zu machen – wo Alpine sie nutzen kann. Dazu müssen die Daten zunächst auf der shops-Property der GearShopList-Komponente in String-Form gebracht werden. Dadurch kann Astro sie serialisieren, wenn es die Ansicht an den Browser sendet (im Wesentlichen wird JSON.stringify(gearShops) in das HTML-Dokument eingefügt). Ein Blick auf GearShopList: --- const { shops, initialCount } = Astro.props; // Receive the 'shops' prop if (!shops) { throw new Error('GearShopList component requires a "shops" prop that is an array.'); } --- All Hiking Climbing () Dieser Code ist relativ selbsterklärend, mit Ausnahme des x-data-Attributs . Der Zweck ist klar: Wir wollen ein JavaScript-Objekt mit einem filter– und einem shops-Feld erstellen, wobei letzteres das Live-JavaScript-Objekt enthält, das wir zuvor auf dem Server erstellt haben. Die zusätzlichen Zeichen sind nötig, um das syntaktisch zu bewerkstelligen. Der Schlüssel, um x-data zu verstehen, ist dabei die {``}-Syntax – geschweifte Klammern mit zwei Backticks –, die zu einem leeren String aufgelöst wird. Soll heißen: Das x-data-Feld ist letztendlich ein String-Literal-Objekt, das die shops-Variable als JSON interpoliert. Alpine verarbeitet all das und wandelt es in ein Live-Objekt um, um die Komponente zu steuern (die Funktionsweise dieses Anwendungsteils lässt sich auch anhand dieser Astro-Alpine-Demo-Anwendung auf GitHub nachvollziehen). Neben dem x-data-Attribut bindet x-model den Auswahlwert an die filter-Variable. Mit x-for können wir über Shops iterieren. So sieht unsere “Gear Shops”-Seite nun aus: Matthew Tyson Ebene 3: Die “Adventures”-Seite Im Fall der “Adventures”-Seite kommt schließlich Alpine zum Zug. Damit Astro nicht in Sachen SSG tätig wird, ist es an dieser Stelle nötig, seine Pre-Rendering-Funktion zu deaktivieren. --- import Layout from '../layouts/Layout.astro'; export const prerender = false; // Important: Disable prerendering for this page --- My Adventures Loading adventures... {/*... other adventure details... */} Diese Seite demonstriert die Vielseitigkeit und Performanz von Alpine: Das x-data-Attribut enthält sowohl die data-Property (adventures) als auch eine Fetching-Methode (fetchAdventures()). Wird x-init bei der Initialisierung der Komponenten aufgerufen, callt es die fetchAdventures()-Funktion, die wiederum unseren Server aufruft und adventures mit Daten befüllt. Dabei ist alles übersichtlich in einem kleinen Bereich zusammengefasst, in dem Daten, Verhalten und Ansicht logisch miteinander verknüpft sind. Anschließend verwenden wir x-if, um auf Basis von adventures.length entweder eine Loading Message oder die eigentliche Liste anzuzeigen. Die Adventures-API Zu guter Letzt benötigen wir noch einen Backend-Endpunkt, um die Adventures-JSON für diesen Call bereitzustellen: export async function GET() { const adventures = [ { id: 1, title: "Hiking Trip to Mount Hood", date: "2024-08-15" }, { id: 2, title: "Kayaking Adventure on the Rogue River", date: "2024-09-22" }, //... more adventures ]; return new Response(JSON.stringify(adventures), { status: 200, headers: { 'Content-Type': 'application/json' } }); } Ein Blick auf unsere “Adventures”-Seite: Matthew Tyson (fm) Sie wollen weitere interessante Beiträge zu diversen Themen aus der IT-Welt lesen? Unsere kostenlosen Newsletter liefern Ihnen alles, was IT-Profis wissen sollten – direkt in Ihre Inbox!