Arbeit · 2026
Dieses Portfolio
Der Nachfolger einer PHP-Anwendung mit 33.000 Zeilen, jetzt statisch, zweisprachig und ohne Datenbank.
Auf einen Blick
- Ohne Backend, Datenbank und Login, komplett statisch ausgeliefert
- Inhalte als Markdown, beim Build von einem Zod-Schema geprüft
- Zweisprachig DE/EN, Deutsch ohne Präfix direkt auf der Root
- Interaktive Teile in Vanilla-TypeScript statt in einem UI-Framework
Warum neu gebaut
Die Vorgängerversion war ein eigenes PHP-MVC-Framework mit elf Controllern, acht Models und dreizehn Datenbanktabellen. Sie konnte Benutzerkonten mit TOTP und Passkeys, ein Ticketsystem mit KI-Chatbot, vier Spiele mit OpenAI-Gegnern und einen E-Auto-Laderechner.
Für das, wofür die Seite eigentlich da war, blieb dabei wenig übrig: Projekte zeigen. Die Projektübersicht bestand aus drei Seiten, und die Inhalte lagen in einer MySQL-Tabelle, also außerhalb von Git und ohne Versionsverlauf.
Was übrig geblieben ist
Authentifizierung, Tickets, Spiele, Rechner, Datenbank und Server-Code sind weggefallen.
Geblieben ist eine statische Seite auf demselben Apache-Host wie vorher, nur eben als
dist/-Ordner statt als Front-Controller.
Die Projektinhalte liegen als Markdown im Repository, und ein Zod-Schema in
content.config.ts prüft beim Build jedes Feld. Ein fehlendes Jahr, eine kaputte URL oder ein
Projekt, das nur in einer Sprache existiert, lässt npm run build fehlschlagen, bevor etwas
davon online geht.
Warum kein CMS
Ein Admin-Bereich hätte wieder einen Server, Sessions und eine Passwortverwaltung gebraucht, also genau das, was beim Neubau wegfallen sollte. Ein neues Projekt besteht stattdessen aus einer Datei pro Sprache und einem Commit. Rollback, Diff und Historie kommen von Git.
Frontend
Die interaktiven Teile sind ein paar kleine TypeScript-Inseln: Filter und Suche in der Projektliste, die Befehlspalette, der Theme-Wechsel und ein Spotlight-Effekt, der dem Mauszeiger folgt. Für ein UI-Framework ist das zu wenig. Ohne JavaScript bleibt die Liste einfach ungefiltert.
Die drei Farbschemata der alten Seite gibt es weiterhin: Noir als Standard, Hell und Sakura als
Alternativen. Alle Animationen liegen hinter prefers-reduced-motion.