Zeitraum
– heute
Auftraggeber
Eigenes Projekt

Kennzahlen

Cookies auf Inhaltsseiten
0
Requests an fremde Domains
0
geprüfte Viewports, 320 bis 2560 px
17
Browser-Engines im Test
3

Kontext

Diese Seite ist gleichzeitig Visitenkarte und Arbeitsprobe. Wer sie liest, steht bereits darauf — jede Behauptung über Performance, Barrierefreiheit oder Datenschutz lässt sich mit einem Blick in die Entwicklerwerkzeuge des Browsers überprüfen. Das ist die Messlatte: Eine Entwicklerseite, die ihre eigenen Ansprüche nicht einhält, widerlegt ihre Werbebotschaft.

Die Vorgaben waren entsprechend hart: kein Cookie-Banner, weil keine Cookies ohne Grund; keine Schriften, Skripte oder Analysen von fremden Servern; Lesbarkeit ohne JavaScript; WCAG 2.2 AA auf jeder Seite.

Problem

Die Anforderungen widersprachen sich an einer Stelle, die erst beim genauen Hinsehen auffällt. Die Seite sollte aus einem Full-Page-Cache kommen — praktisch jede Antwort als fertige HTML-Datei. Gleichzeitig gibt es ein Kontaktformular mit CSRF-Token, Honeypot und Zeitfalle.

Beides zusammen ist nicht baubar. Ein gecachter CSRF-Token wird an jeden Besucher ausgeliefert; ab dem zweiten bekommt jeder beim Absenden HTTP 419. Der einzige Konversionspfad der Seite wäre tot gewesen — und kein Monitoring hätte angeschlagen, weil die Seiten selbst fehlerfrei laden.

Lösung

Cache-Zonen an der Route

Statt einer Ausschlussliste deklariert jede Route ihre Zone selbst: Inhaltsseiten gecacht und sessionlos, das Formular ungecacht mit Session und CSRF, Maschinen-Endpunkte wie robots.txt gecacht ohne HTML. Ein Test iteriert über alle registrierten Routen und bricht ab, sobald eine keiner Zone angehört. Wer später ein Formular ergänzt und die Cache-Ausnahme vergisst, bekommt einen roten Build statt eines stillen Fehlers.

Laravels Standardgruppe bewusst nicht verwendet

Beim Aufsetzen zeigte sich, dass Laravel die Middleware-Gruppe web automatisch über jede Route der Routendatei legt — inklusive StartSession. Damit setzte auch die Startseite ein Session-Cookie. Die Routen werden deshalb ohne implizite Gruppe registriert, und die Session existiert ausschließlich auf der Kontaktseite. Beim selben Umbau fiel auf, dass der CSRF-Schutz in der Formulargruppe fehlte: Ein Test hatte die tatsächlich gesetzten Cookies gelesen und XSRF-TOKEN vermisst.

Verworfene Alternativen

  • Alpine.js für Drawer, Theme-Umschalter und Akkordeon. Das Akkordeon ist natives <details>, der Rest sind rund 70 Zeilen eigenes JavaScript. 15 KB Framework dafür passten nicht zu einer Seite, die sich als Arbeitsprobe versteht.
  • Ein CMS. Alle Inhalte liegen versioniert als YAML und Markdown im Repository. Jeder Fakt existiert genau einmal und speist HTML, JSON-LD und llms.txt — Widersprüche zwischen den Ausgaben sind damit strukturell ausgeschlossen statt redaktionell vermieden.
  • Paginierung über Query-Parameter. Blogseiten liegen unter /blog/seite/2, nicht unter ?seite=2.

Tests, die dort prüfen, wo der Fehler entsteht

Die Layouttests laufen durch 17 Viewports von 320 bis 2560 Pixel, jeweils an beiden Rändern der Breakpoints — Layoutfehler sitzen fast immer an der Umschaltgrenze, nicht in der Mitte. Dazu Chromium, Firefox und WebKit. Geprüft werden Überlauf, Trefferflächen, axe-core, Textabstände nach WCAG 1.4.12 und der Zustand ohne JavaScript.

Stack

Komponente Technologie Begründung
Framework Laravel 13 Routing, Middleware-Gruppen und Tests aus einer Hand
Templates Blade-Komponenten Server-seitig gerendert, vollständig ohne JavaScript lesbar
Styles Tailwind CSS 4 Design-Tokens mit nachgerechneten Kontrastwerten
Build Vite 8 Ein Stylesheet, ein Skript, keine Laufzeit-Abhängigkeiten
Inhalte YAML und Markdown Versioniert, validiert, eine Quelle für alle Ausgaben
Tests Pest und Playwright Anwendung und Auslieferung getrennt geprüft

Ergebnis

  • Kein Cookie auf Inhaltsseiten — deshalb auch kein Cookie-Banner
  • Kein Request an eine fremde Domain, im Browser-Test auf Netzwerkebene geprüft
  • 17 Viewports und 3 Engines in jedem Testlauf
  • Eine Sitemap, die aus den registrierten Routen entsteht und nicht von Hand gepflegt wird

Was ich daraus gelernt habe

Die meisten Fehler dieses Projekts sind still aufgetreten: ein fehlender CSRF-Schutz, ein Session-Cookie auf der Startseite, eine statische robots.txt, die die erzeugte überschattete. Keiner davon hätte eine Fehlermeldung erzeugt. Gefunden hat sie jeweils ein Test, der den tatsächlichen Zustand gelesen hat statt den erwarteten — und genau das ist seitdem die Frage, die ich an jeden Test stelle.

Firmenprojekt? Projekte für Unternehmen laufen über twentyonepixels — dort gibt es Leistungen, Konditionen und Referenzen. twentyonepixels.de