Astro - Statischer Website Generator
Astro ist ein modernes, leistungsstarkes Frontend-Framework für den Aufbau statischer und dynamischer Webseiten. Es ist besonders für Content-getriebene Websites wie Blogs, Dokumentationen und Marketingseiten optimiert.

Inhaltsverzeichnis
Merkmale von Astro
- Statische Generierung: Standardmäßig rendert Astro Seiten als statische HTML-Dateien für maximale Performance.
- Inhaltsfokus: Ideal für Blogs und Dokumentationen, unterstützt Markdown und MDX nativ.
- Komponenten-Agnostisch: Unterstützt React, Vue, Svelte, Solid, Preact und mehr – du kannst verschiedene Frameworks in einem Projekt mischen!
- On-Demand JavaScript: Standardmäßig wird kein JavaScript im Browser geladen, außer es wird explizit benötigt.
- SSG & SSR: Unterstützt sowohl Static Site Generation (SSG) als auch Server-Side Rendering (SSR).
- Optimierte Performance: Sehr schnelle Ladezeiten durch automatische Optimierung von Assets.
Warum Astro?
Eigentlich hat mich ein Arbeitskollege auf Astro aufmerksam gemacht. Er hat damit eine statische Webseite erstellt, und ich fand die Organisation sehr elegant. Bei der Erstellung meines neuen Homelab k3s Clusters benötigte ich dann auch ein schönes Beispiel-Deployment. Daher habe ich die beiden Projekte kurzerhand zusammengeführt.
Zielsetzung
Zum einen wollte ich eine relativ hübsche Website erstellen und zum anderen die Funktionen von Astro erforschen. Vorher habe ich für solche Seiten Hugo eingesetzt. Allerdings war mir das Erstellen von Templates/Themes einfach zu aufwändig. Zudem nutzen die meisten Vorlagen unzählig viel JavaScript und andere Ressourcen, um hübsch auszusehen. Natürlich geht das auf Kosten der Performance, denn das Laden all dieser Ressourcen kostet Zeit.
Laden von Inhalten
Hier mal die Hardware Seite wie sie in Astro ausschaut.
---import Layout from "../layouts/BaseLayout.astro";import { Image } from 'astro:assets'import { getCollection } from "astro:content";const images = import.meta.glob('./images/*.{jpg,jpeg,png,svg}');
// Hardware Content Collectionsconst devices = await getCollection("hardware");console.log(images);---
<Layout title="Hardware"> <h1>Homelab Hardware</h1>
<div class="device-container">
{devices.map((device) => <div class="device">
<Image src={`${device.data.image.src}`} alt={`${device.data.image.alt}`} height={300} width={300} format="webp" class="device-image" />
<h2>{device.data.model}</h2> <p><strong>Name:</strong> {device.data.name}</p> <p><strong>Operating System:</strong> {device.data.operating_system}</p> <p><strong>Processor:</strong> {device.data.processor}</p> <p><strong>Memory:</strong> {device.data.memory}</p> <p><strong>Storage:</strong> {device.data.storage}</p> <p><strong>Network:</strong> {device.data.network}</p> <p><strong>Description:</strong> {device.data.description}</p> <p><strong>Applications:</strong></p>
<ul> {device.data.applications.map(app => ( <li>{app}</li> ))} </ul>
</div>)} </div></Layout>
Die Daten werden mittels einer Collection geladen. Die Collection besteht in diesem Fall aus einem Verzeichnis in dem einzelne YAML Dateien liegen.
src/content/hardware/├── neo.yml├── raspberrypi4.yml└── zion.yml
Hier mal eine Datei um die Struktur zu sehen:
name: zionimage: src: /images/hardware/zion.jpg alt: Ziondescription: Der Lenovo ThinkCentre M920q Tiny ist mein Proxmox Host.model: Lenovo ThinkCentre M920q Tinyoperating_system: Debian 12memory: 32GBprocessor: X86 Intel® i7-8700T (6 cores,12 threads,2.4GH//4.0GHz turbo)storage: 2x 1024GB NVMe SSDnetwork: 1x 1GBit, 1x 2.5GBitapplications: - Proxmox - Forgejo Runner - k3s - AdGuard - Crowdsec - Excalidraw - FHEM - grocy - homepage - mqtt - portainer - stirlingpdf - tasmotadmin - traefik - watchtower - zigbee2mqtt - Home Assistant - InfluxDB - immich - paperless - weechat
Weitere Verwendung der Dateien
Man kann diese Collections nicht nur nutzen um Inhalte auf der Seite anzuzeigen, sondern auch einen API Endpoint zur Verfügung stellen.
import { getCollection } from "astro:content";
const devices = await getCollection("hardware");
export const GET = async ({ }) => {
if (!devices) { return new Response(null, { status: 404, statusText: 'Not found' }); }
return new Response(JSON.stringify(devices), { headers: { "content-type": "application/json", }, status: 200, });};
Der Code stellt den folgenden Endpunkt zur Verfügung:
https://www.trinityonline.de/api/hardware
Mittells curl könnt ihr euch die Ausgabe auch auf der Konsole anzeigen lassen.
curl https://www.trinityonline.de/api/hardware | jq`
Die Ausgabe von curl:
[ { "id": "zion", "data": { "name": "zion", "image": { "src": "/images/hardware/zion.jpg", "alt": "Zion" }, "description": "Der Lenovo ThinkCentre M920q Tiny ist mein Proxmox Host.", "model": "Lenovo ThinkCentre M920q Tiny", "operating_system": "Debian 12", "memory": "32GB", "processor": "X86 Intel® i7-8700T (6 cores,12 threads,2.4GH//4.0GHz turbo)", "storage": "2x 1024GB NVMe SSD", "network": "1x 1GBit, 1x 2.5GBit", "applications": [ "Proxmox", "Forgejo Runner", "k3s", "AdGuard", "Crowdsec", "Excalidraw", "FHEM", "grocy", "homepage", "mqtt", "portainer", "stirlingpdf", "tasmotadmin", "traefik", "watchtower", "zigbee2mqtt", "Home Assistant", "InfluxDB", "immich", "paperless", "weechat" ] }, "filePath": "src/content/hardware/zion.yml", "digest": "107e1e3b3dc0e223", "collection": "hardware" }, { "id": "neo", "data": { "name": "neo", "image": { "src": "/images/hardware/neo.png", "alt": "Neo Image" }, "description": "Das Ugreen 4800 Plus ist mein zweiter Proxmox Host und mein Haupt NAS System", "model": "Ugreen 4800 Plus", "operating_system": "Debian 12 (Bookworm)", "memory": "32GB", "processor": "X86 Intel® Pentium® Gold 12. Gen 5 Kerne 6 Threads", "storage": "2x2TB NVMe SSD, 2x8TB WD Red", "network": "1x 2.5 GBit, 1x 10GBit", "applications": [ "Proxmox", "TrueNAS-trinity", "Forgejo Runner", "k3s" ] }, "filePath": "src/content/hardware/neo.yml", "digest": "ea33780c77232ca9", "collection": "hardware" }, { "id": "raspberrypi4", "data": { "name": "raspberrypi4", "image": { "src": "/images/hardware/raspberrypi4.jpg", "alt": "Rpi4" }, "description": "Der pi4 hostet im wesentlich noch mein FHEM, da ich noch eine Reihe von Homematic bidcos Komponenten im Einsatz habe.", "model": "Raspberry Pi 4 Model B", "operating_system": "Rasbian 11", "memory": "8GB", "processor": "Quad-core Cortex-A72 (ARM v8) 64-bit SoC @ 1.5GHz", "storage": "USB SSD 256GB", "network": "1x 1GBit", "applications": [ "MQTT Broker", "traefik", "watchtower", "eufy security ws", "FHEM", "SDM630", "Grafana", "Prometheus", "Uptime Kuma", "nginx - tasmato", "pihole", "rtsp" ] }, "filePath": "src/content/hardware/raspberrypi4.yml", "digest": "b4b2644ef701ba8e", "collection": "hardware" }]