37 Punkte von GN⁺ 2025-11-03 | 2 Kommentare | Auf WhatsApp teilen
  • Die URL-Struktur fungiert nicht nur als einfache Adresse, sondern auch als Mittel zum Speichern und Wiederherstellen von Anwendungszustand
  • Am Beispiel der PrismJS-Download-Seite wird gezeigt, wie sich mit einer einzigen URL Theme-, Sprach- und Plugin-Einstellungen vollständig reproduzieren lassen
  • Einzelne Bestandteile wie Pfad, Query-Parameter und Fragment drücken unterschiedliche Zustände aus, etwa hierarchische Navigation, Filterung oder Client-Navigation
  • Suchfilter, Paginierung, Ansichtsmodus und Datumsbereich eignen sich gut für die URL, während sensible Informationen oder flüchtige UI-Zustände ungeeignet sind
  • Gut gestaltete URLs erhöhen Teilbarkeit, Vorhersagbarkeit und Cache-Effizienz und stärken damit Zuverlässigkeit und Nutzererlebnis von Webanwendungen

Das Potenzial der URL

  • Eine URL ist nicht nur eine einfache Ressourcenadresse, sondern fungiert auch als Benutzeroberfläche (UI) und Zustandscontainer
    • Über Teilen, Lesezeichen, Browser-Verlauf und Deep Links bleibt Zustand automatisch erhalten
    • Seit 1991 dient sie als grundlegender Mechanismus zur Zustandsverwaltung im Web
  • Jeder Bestandteil einer URL drückt eine andere Art von Zustand aus
    • Pfad (Path): hierarchische Ressourcennavigation (/users/123/posts)
    • Query: Filter, Optionen, Einstellungen (?theme=dark&lang=en)
    • Fragment: Position innerhalb eines Dokuments oder SPA-Routing (#features, #/dashboard)
  • Die Funktion Text Fragments ermöglicht Direktlinks zu bestimmtem Text innerhalb einer Seite

Muster für Query-Parameter

  • Mehrere Werte können mit einem Trennzeichen (delimiter) unter einem Schlüssel zusammengefasst werden (?tags=frontend,react,hooks)
  • Verschachtelte Daten lassen sich als JSON oder Base64 serialisieren (?config=eyJyaWNrIjoicm9sbCJ9==)
  • Boolesche Flags können durch die bloße Existenz eines Schlüssels dargestellt werden (?mobile)
  • Die Array-Notation (bracket notation) stellt mehrere Werte in der Form tags[]=frontend&tags[]=react dar
    • Wird von qs in Node oder Express-Middleware automatisch erkannt, ist aber nicht standardisiert
  • Entscheidend ist, Konsistenz beizubehalten

Beispiele für Zustandsdarstellung per URL

  • PrismJS: Speichert komplette Einstellungen für Theme, Sprache und Plugins im URL-Hash
  • GitHub: Hebt mit #L108-L136 einen bestimmten Bereich von Codezeilen hervor
  • Google Maps: Enthält Koordinaten, Zoom-Stufe und Kartentyp in der URL
  • Figma: Teilt Arbeitskontext wie Canvas-Position, Zoom und ausgewählte Elemente per URL
  • E-Commerce-Websites: Legen Filter, Sortierung und Preisbereich in der URL ab, um den Suchzustand wiederherzustellen

Frontend-Engineering-Muster

  • Zustände, die sich für die URL eignen
    • Suchbegriffe, Filter, Seiten- und Sortierzustand, Ansichtsmodus, Datumsbereich, aktiver Tab, UI-Konfiguration, Feature-Flags
  • Zustände, die sich nicht für die URL eignen
    • Sensible Informationen wie Passwörter oder Tokens, temporäre UI-Zustände, ungespeicherte Eingaben, große Datenmengen, Zustände mit hoher Änderungsfrequenz
  • Maßstab für die Entscheidung: Soll ein anderer Nutzer beim Klick auf dieselbe URL denselben Zustand sehen?

JavaScript-Implementierung

  • Mit der API URLSearchParams lassen sich Query-Parameter lesen und schreiben
  • pushState fügt einen neuen Verlaufseintrag hinzu, replaceState aktualisiert den aktuellen Eintrag
  • Über das Ereignis popstate kann die UI beim Zurück-Navigieren im Browser wiederhergestellt werden

React-Implementierung

  • Mit dem Hook useSearchParams aus React Router lässt sich URL-Zustand kompakt verwalten
    • Beim Lesen und Aktualisieren von Parametern werden URL und UI automatisch synchronisiert

Best Practices für URL-Zustandsverwaltung

  • Standardwerte nicht in die URL aufnehmen (?theme=dark beibehalten, Standardwerte im Code behandeln)
  • Mit Debouncing übermäßige URL-Aktualisierungen während der Eingabe vermeiden (lodash.debounce verwenden)
  • pushState vs replaceState
    • pushState: für rückgängig machbare Zustände wie Filteränderungen oder Seitenwechsel
    • replaceState: für feingranulare Änderungen wie Sucheingaben

Die URL als Vertrag verstehen

  • Eine gut gestaltete URL fungiert als expliziter Vertrag zwischen Anwendung und Nutzer
    • Sie macht Grenzen zwischen öffentlich/privat, Client/Server und geteiltem/sitzungsgebundenem Zustand klar
  • Gut lesbare URLs machen Absichten verständlich und sind für Menschen wie Maschinen gleichermaßen nachvollziehbar
    • Eine Form wie example.com/products/laptop?color=silver&sort=price vermittelt Bedeutung besonders gut
  • Verbesserte Cache-Effizienz
    • Dieselbe URL gilt als dieselbe Ressource, was die Cache-Trefferquote erhöht
    • Über Query-Parameter lassen sich Cache-Varianten steuern
  • Versionsverwaltung und Experimente
    • API-Versionen und A/B-Tests lassen sich mit ?v=2, ?beta=true, ?experiment=new-ui unterscheiden

Antipatterns, die man vermeiden sollte

  • In SPAs nur In-Memory-Zustand halten, wodurch der Zustand beim Neuladen verloren geht
  • Sensible Informationen in die URL aufnehmen (?password=secret123)
  • Unklare Parameternamen (?foo=true&bar=2 statt ?mobile=true&page=2)
  • Komplexes JSON in Base64 kodieren und dadurch übermäßig lange URLs erzeugen
  • URL-Längenlimits überschreiten (es gibt Beschränkungen bei Browsern, Servern und CDNs)
  • Den Zurück-Button entwerten (durch übermäßige Verwendung von replaceState)

Fazit

  • Eine gute URL verweist nicht nur auf Inhalte, sondern drückt den Dialog zwischen Nutzer und Anwendung aus
  • Die URL ist das älteste und eleganteste Mittel der Zustandsverwaltung für Absicht, Kontext und Teilbarkeit
  • Es gibt zwar komplexe Tools zur Zustandsverwaltung wie Redux, MobX, Zustand und Recoil,
    aber die grundlegende Funktion der URL nicht zu vergessen, ist die eigentliche Stärke des Webs
  • Eine App, die beim Neuladen ihren Zustand verliert, verfehlt eine wesentliche Eigenschaft des Webs

2 Kommentare

 
GN⁺ 2025-11-03
Hacker-News-Kommentare
  • Beim Code-Review versuche ich, möglichst viel Status (state) in der URL zu speichern
    Dass man nach dem Neuladen an einer völlig anderen Stelle landet oder eine geteilte URL einen ganz anderen Bildschirm zeigt, ist aus Nutzersicht eine Zumutung
    Dieser Ansatz verlangsamt zwar die Entwicklung, aber im Team steigt dadurch das UX-Bewusstsein, und man sieht klarer, wie viel Status in einer View steckt
    Es gibt zwar die Sorge, dass die URL zu einer Art öffentlicher API wird und dadurch Einschränkungen entstehen, aber die meisten URLs werden ohnehin nur kurzfristig genutzt, daher halte ich das für kein großes Problem
    Falls nötig, lässt sich das mit Code lösen, der beim Laden alte URLs auf neue URLs migriert

    • Ich mag diesen Ansatz, aber wegen der automatischen Vervollständigung des Browserverlaufs wird manchmal unerwünschter Status wieder geladen
      Ich denke, mit Query-Parametern statt des Pfads wäre es etwas besser
    • Eine Web-App, die ich beruflich nutze, hat einen eigenen „Zurück“-Button gebaut, wodurch die Zurück-Funktion des Browsers komplett kaputt ist
      Aus Nutzersicht ist das verwirrend, weil das Wort „Zurück“ mit dem Browser-Button verknüpft ist
      Dass ein Neuladen den Status zurücksetzt, ist weniger nervig. Denn „Neu laden = von vorn anfangen“ ist ein verbreitetes mentales Modell
    • Bei serverseitig gerenderten Seiten wird beim Neuladen die Scroll-Position automatisch wiederhergestellt
      Wenn alles mit JS verarbeitet wird, gehen solche Grundfunktionen oft auf subtile Weise kaputt
    • Ich finde, URL-Design ist Teil des UX-Designs
      Trotzdem habe ich in der Zusammenarbeit mit über 30 UX-Designern noch nie Richtlinien zu URLs bekommen
    • Mit der Weiterentwicklung des Webs hat sich die Bedeutung des Neuladens je nach Situation verändert
      Gerade auf Mobilgeräten ist es oft schwer, eine Seite in den Ausgangszustand zurückzubringen, sodass Neuladen die schnellste Lösung ist
      Bei Infinite Scroll oder komplexen Filter-UIs ist das Zurücksetzen umso lästiger, je mehr Status in der URL steckt
      Wenn man ohnehin schon mit einer schlechten UX kämpft und dann auch noch die URL aufräumen muss, ist das für Nutzer doppelter Stress
  • Ich habe das Gefühl, dass selbst digital versierte Menschen URL und DNS nur schlecht verstehen
    Man sollte Phishing-Risiken verringern können, die Bedeutung von URL-Parametern (?t=_, utm_) verstehen und vor dem Teilen personenbezogene Daten entfernen können
    Man sollte auch wissen, dass das HTTPS-Schloss nicht automatisch „Vertrauen“ bedeutet

    • Gleichzeitig ist Aufklärung schwierig, weil Browser URLs standardmäßig verbergen oder kürzen und Unternehmen oft nur QR-Codes oder Suchbegriffe bewerben
  • Wenn man URLs als Status-Container verwendet, wird die interne Struktur offengelegt, und Versionierung wird notwendig
    Auch bei Browser-Kompatibilität oder Authentifizierungsabläufen kann es Probleme geben
    Trotzdem versuche ich, möglichst viel Status in der URL offenzulegen, ähnlich wie bei Kommandozeilenargumenten
    Das ist jedoch ein bewusster Trade-off und nicht das Ergebnis von Unwissen oder mangelnder Erfahrung

  • Ich empfehle Rison, eine alte Bibliothek, die aber immer noch nützlich ist
    Damit lässt sich JSON sauber in einer URL speichern, und sie wird auch in Elastic Kibana verwendet
    Beispiel: http://example.com/service?query=q:'*',start:10,count:10

    • Genau nach so etwas habe ich gesucht! Früher habe ich mir immer provisorisch selbst etwas gebaut, aber das hier wirkt wie eine viel standardisiertere und aufgeräumtere Lösung
  • Wenn sich ein System weiterentwickelt, ändert sich auch die Statusstruktur, daher schränkt Status in der URL die Evolution ein
    Denn URLs sind im Grunde permanente Zeichenketten
    Stattdessen sollte man die URL eher als eine Art Protokoll betrachten und den Status entsprechend kodieren und dekodieren
    Bei einfachen Seiten kann man durchaus den gesamten Status in die URL legen

    • Bei Inhalten mit langer Lebensdauer (z. B. Blogposts) ist die Bewahrung des URL-Status nützlich
      Bei Feeds hängt es jedoch von den Nutzererwartungen ab, etwa davon, ob ein Neuladen wieder den neuesten Zustand zeigen soll
    • Mit Versionierung lässt sich dieses Problem abmildern
  • Das URL-Längenlimit hängt von Browser-, Server-, CDN- und Suchmaschinen-Einstellungen ab, liegt aber meist unter 2000 Zeichen
    Daher stellt sich die Frage, wie viel Status sich innerhalb dieser Grenze unterbringen lässt oder ob ein anderer Ansatz nötig ist

    • Für jedes Zeichen außer der Domain stehen 66 Möglichkeiten zur Verfügung (Groß- und Kleinbuchstaben, Zahlen und die Sonderzeichen - . _ ~), daher ist die Informationsdichte ziemlich hoch
  • draw.io kann den gesamten Status in der URL speichern und so teilbar machen
    Die Diagrammdaten werden in Base64 kodiert, sodass eine vollständige Wiederherstellung über einen einzigen Link möglich ist
    Ich bin mir nur nicht sicher, ob das wirklich unter die Definition eines „state container“ fällt

  • Ich verwende in selbstgehosteten Apps Hash-Routing (#/dashboard)
    Dadurch braucht man keine serverseitigen URL-Rewrites (.htaccess usw.), was zwar nicht perfekt ist, aber die Einschränkungen der Deployment-Umgebung verringert

  • Das aktuelle Microsoft Teams behandelt alle Ansichten über eine einzige URL und ist daher nicht bookmarkbar
    Man kann ein bestimmtes Team oder einen bestimmten Kanal nicht direkt öffnen, was extrem unpraktisch ist

  • HATEOAS bekommt wegen seines Namens nicht viel Aufmerksamkeit, ist aber letztlich ein Grundkonzept des Webs

    • Aus Nutzersicht ist HATEOAS einfach das Folgen von Links und das Absenden von Formularen
      In Umgebungen, in denen man Server und Client vollständig kontrolliert, erzeugt es jedoch nur zusätzliche Komplexität
      Besonders wenn der Client die Struktur der Endpunkte trotzdem kennen muss, macht es URLs nur undurchsichtiger
    • Dieses Thema hat mit HATEOAS eigentlich nichts direkt zu tun. Beide verwenden zwar URLs, aber bei HATEOAS geht es nicht um Zustandsspeicherung, sondern um die Navigationsstruktur
    • Als Scherz gesagt: Eigentlich passt zu HATEOAS eher der Begriff „cerealization
 
ndrgrd 2025-11-03

Ich nutze die Tab-Energiesparfunktion sehr gern, aber bei Web-Apps, die einen fixierten URL haben und als ein Block funktionieren, gehen beim Wechsel in den Energiesparmodus Informationen verloren.

Andererseits sind genau solche Webseiten ausnahmslos so schwergewichtig, dass man den Energiesparmodus auch nicht einfach deaktivieren kann.