Logo von Miran Arnaut Logo von Miran Arnaut
Development 6 Min. Lesezeit

Wie und warum ich diese Website gebaut habe

Von WordPress zu Astro, von dynamisch zu statisch, von fremdbestimmt zu selbstbestimmt. Ein Blick auf den kompletten Neuaufbau von miran.at.

Fünf Jahre lang lief miran.at auf WordPress. Es hat funktioniert — aber es hat sich nie richtig angefühlt.

Jedes Update brachte neue Abhängigkeiten. Jedes Plugin fügte JavaScript hinzu, das niemand bestellt hatte. Der Page Builder kämpfte gegen das Theme, das Theme kämpfte gegen das Cache-Plugin, und ich kämpfte gegen alle drei.

Irgendwann fragte ich mich: Warum betreibe ich einen ganzen CMS-Backend-Server für eine Website, die sich kaum ändert? Warum laden Besucher 500 KB JavaScript, nur um einen Blog-Artikel zu lesen?

Die Antwort war: tue ich nicht mehr.

Die Ausgangslage

miran.at war eine klassische WordPress-Seite mit einem massgeschneiderten Theme, das ich selbst entwickelt hatte. Es sah gut aus, aber unter der Haube war es ein Kompromiss.

Der grösste Schmerzpunkt war WordPress selbst. Nicht weil WordPress schlecht wäre — es ist ein hervorragendes CMS für Kundenprojekte. Aber für meine eigene Website war es overengineered. Ich brauchte kein Admin-Panel, kein WYSIWYG, kein Media-Library-Management. Ich brauchte Markdown-Dateien, ein Git-Repository und einen Build-Prozess, der eine statische Website ausspuckt.

Dazu kamen:

  • Performance: WordPress-Seiten sind ohne aggressive Caching-Strategie nicht schnell. Und Caching macht das Backend-Panel teilweise unbrauchbar.
  • Sicherheit: Jede WordPress-Installation ist ein Angriffsziel. Updates, Hardening, Monitoring — alles zusätzlicher Aufwand.
  • Abhängigkeit: Ein MySQL-Database-Server, ein PHP-FPM-Prozess, regelmäßige Backups. Für eine statische Website.
  • Kreative Freiheit: WordPress zwingt einem eine bestimmte Denkweise auf. Posts, Pages, Custom Post Types, Taxonomien. Ich wollte Content so organisieren, wie es für mich Sinn ergibt — nicht wie WordPress es vorgibt.

Die Technologie-Entscheidungen

Astro — Das Fundament

Astro war von Anfang an die richtige Wahl. Die Kernphilosophie — null JavaScript im Standard, statisches HTML als Output — trifft genau meinen Anwendungsfall.

Ich habe mir andere Static-Site-Generatoren angesehen:

  • Next.js ist ein App-Framework, verkleidet als Static-Site-Generator. Für eine Content-Seite zu schwer.
  • Hugo ist blitzschnell, aber die Template-Sprache fühlt sich an wie ein Rückschritt.
  • Eleventy ist solide, aber ohne integrierte Island-Architektur müsste ich Interaktivität selbst lösen.
  • Astro bietet das beste Gesamtpaket: Type-Safe Content Collections, Island Architecture, Vue/React/MDX-Support, und eine hervorragende DX.

Entscheidend waren für mich die Content Collections. Ein Zod-Schema definiert, welche Frontmatter-Felder ein Blog-Post haben muss. Fehlt ein Feld oder hat es den falschen Typen — der Build bricht ab. Das klingt hart, aber es verhindert genau die Fehler, die bei Content-Seiten am häufigsten auftreten.

Vue 3 — Die interaktiven Inseln

Nicht jede Interaktion braucht ein SPA. Astro’s Island Architecture erlaubt mir, Vue-Komponenten nur dort einzusetzen, wo sie wirklich gebraucht werden: animierte Texte, einen Cookie-Consent-Dialog, Scroll-Animationen.

Warum Vue und nicht React oder Svelte?

  • Vue fühlt sich für mich natürlicher an. Single-File-Components mit <template>, <script> und <style> in einer Datei entsprechen meiner mentalen Organisation.
  • Die Composition API mit <script setup> ist elegant und typsicher.
  • Vue’s Reaktivitätssystem arbeitet im Hintergrund und erfordert keine manuelle Dependency-Optimierung.

Tailwind CSS 4

Ich war lange kein Tailwind-Fan. Utility-Klassen im HTML fühlten sich falsch an.

Dann habe ich verstanden: Tailwind zwingt dich nicht, keine Semantik zu haben. Es gibt dir einen anderen Abstraktionsgrad — nämlich gar keinen. Statt eine Klasse .hero-headline zu definieren, die in einer components/hero.css-Datei irgendwelche Styles zusammenfasst, siehst du direkt im HTML, welche Styles angewendet werden.

Tailwind CSS 4 mit dem CSS-first-Config-Ansatz (@theme in global.css) ist ein weiterer Schritt nach vorne. Kein tailwind.config.js mehr, sondern echte CSS-Custom-Properties.

GSAP — Motion Design

Animationen auf einer Content-Seite müssen einen Zweck erfüllen. GSAP erlaubt mir, präzise zu steuern, was passiert — und noch wichtiger: wann nichts passiert.

Jede GSAP-Animation ist dynamisch importiert. Wenn ein Besucher prefers-reduced-motion aktiviert hat, läuft keine Animation. Punkt.

ScrollTrigger erzeugt Reveal-Effekte, die den Lesefluss begleiten, ohne ihn zu unterbrechen.

Three.js — Das 3D-Spiel

Ein Portfolio muss nicht langweilig sein. Der interaktive 3D-Bereich (/spiel/) ist ein kleines Experiment — eine spielerische Art, meine Arbeit zu präsentieren.

Three.js lädt nur auf dieser einen Seite. Der Rest der Website bleibt schlank.

Self-Hosting — Docker + nginx

Die Website läuft auf meinem eigenen Server. Ein Docker-Container mit nginx serviert die statischen Dateien. Ein Cloudflared-Tunnel sorgt für SSL und DDoS-Schutz, ohne dass ich Cloudflare’s Proxy umgehen muss.

Alternative Deployment-Wege (rsync zu Webmin) sind vorbereitet, falls ich den Provider wechseln möchte.

Kein CDN, kein externer Hoster für die Assets. Alles selbst gehostet.

i18n — Drei Sprachen

Deutsch, Englisch, Kroatisch. Drei Sprachen, eine Codebasis.

Die Umsetzung war kniffliger als erwartet. Astro’s i18n-System unterstützt prefixDefaultLocale: false für Deutsch als Root-Sprache. Aber die Content-Routes musste ich selbst bauen — buildDefaultBlogStaticPaths() für Deutsch, buildLocalizedBlogStaticPaths() für Englisch und Kroatisch.

Das Route-Manifest in route-manifest.ts definiert für jede Route, in welchen Sprachen sie verfügbar ist und welche URL-Struktur sie hat:

  • Deutsch: /blog/wie-und-warum-ich-diese-website-gebaut-habe/
  • Englisch: /en/blog/how-and-why-i-built-this-website/
  • Kroatisch: /hr/blog/kako-i-zasto-sam-izgradio-ovu-web-stranicu/

Das Design

Swiss Editorial Aesthetic

Die Website sieht nicht aus wie ein Template. Das war das wichtigste Goal.

Inspiriert vom Schweizer Design der 1950er- und 60er-Jahre: Klare Raster, viel Weissraum, Typografie als Gestaltungsmittel, keine Dekoration um der Dekoration willen.

Das 8-Spalten-Raster

Die meisten Websites verwenden 12 Spalten. Ich verwende 8.

Der Unterschied ist subtil, aber wichtig. 8 Spalten zwingen zu klareren Entscheidungen. 2+6, 3+5, 4+4, 8. Es gibt weniger Kombinationen, und das ist gut so.

Drei Farben

#08163C, #7FB5FF, #FFFFFF. Drei Farben. Keine Abstufungen, keine Farbverläufe, kein Schnickschnack.

Im Dark Mode tauschen Vorder- und Hintergrund ihre Rollen. Das Blau bleibt als Akzentfarbe erhalten.

Syne — Ein Schriftgewicht

Syne in Weight 400. Ohne Fett, ohne Halbfett, ohne leicht.

Wenn alles gleich schwer ist, muss die Hierarchie über Grösse und Abstand funktionieren. Das ist anspruchsvoller, aber das Ergebnis ist sauberer.

Die Ziele

1. Performance. Die Website lädt in unter einer Sekunde. Kein JavaScript-Bundle blockiert den Render. Lighthouse ist nicht perfekt — aber konstant über 95.

2. Wartbarkeit. Ein Git-Pull, ein npm run build, ein Docker-Restart. Fertig. Kein WordPress-Update, kein Plugin-Konflikt, kein Datenbank-Migration-Script.

3. Vollständige Kontrolle. Jedes Pixel auf dieser Website ist selbstbestimmt. Kein Theme schreibt mir vor, wie ein Element auszusehen hat. Kein Page Builder limitiert mich auf vordefinierte Blöcke.

4. Mehrsprachigkeit ohne Kompromisse. Drei Sprachen, eine Codebasis. Neue Übersetzungen füge ich hinzu, indem ich eine neue Markdown-Datei erstelle und den translationKey setze.

5. Langlebigkeit. Astro produziert statisches HTML. Statisches HTML funktioniert in 20 Jahren noch. Kein Framework-Upgrade notwendig, kein Runtime-Ende, keine Breaking Changes von React-Versionen.

Was ich gelernt habe

Ein Redesign ist nie nur ein Redesign. Es ist eine Gelegenheit, die eigenen Annahmen zu hinterfragen.

Warum brauche ich ein CMS? Brauche ich wirklich ein Admin-Panel? Ist dynamisch immer besser als statisch? Wie viel JavaScript ist wirklich nötig?

Die Antworten auf diese Fragen haben diese Website geprägt. Und sie haben mich zu einem besseren Entwickler gemacht.

Gebaut mit Astro 5, Vue 3, Tailwind CSS 4, GSAP und Three.js. Selbst gehostet auf eigener Infrastruktur. In drei Sprachen.

So sieht meine Website heute aus. So wird sie für die nächsten Jahre aussehen.

(05) Kontakt aufnehmen

Let’s Talk

Schreib mir eine Nachricht oder verbinde dich über Social Media.