diff --git a/docs/13-entscheidungen.md b/docs/13-entscheidungen.md index 6c31abb..db6222a 100644 --- a/docs/13-entscheidungen.md +++ b/docs/13-entscheidungen.md @@ -1081,3 +1081,29 @@ und keiner ist. Sekunden. Der Aufwand, so einen Fehlschlag einmal falsch zu deuten, ist grösser. `KEEP_TEST_DB=1` behält den Bestand, für das schnelle Nacheinander an einer einzelnen Testdatei. Eine Sicherung im Skript besteht darauf, dass der Name auf `_test` endet. + +### Das Nonce am Themenskript wird nicht hydriert + +Das Skript, das das Thema vor dem ersten Malen setzt, braucht ein Nonce, sonst blockiert die +Inhaltsrichtlinie es und beim Laden blitzt das falsche Thema auf. Genau dieses Nonce erzeugte +aber bei jedem Seitenaufruf eine Hydrierungsmeldung in der Konsole. + +Der Grund liegt nicht bei uns: **der Browser leert das Nonce-Attribut, sobald er das Element +geparst hat.** Das schreibt die CSP-Spezifikation so vor, damit kein Skript den Wert über +`getAttribute` auslesen und sich damit selbst nachladen kann. React vergleicht beim Hydrieren +trotzdem das Attribut, liest clientseitig den leeren Wert und meldet einen Unterschied, den es +nicht gibt — unser Markup ist auf beiden Seiten dasselbe. + +Deshalb `suppressHydrationWarning` an diesem einen Element. Kein Verstecken eines Problems: es +sagt React, dass hier nichts zu vergleichen ist, und das stimmt. Die Alternative wäre, das +Skript statt über das Nonce über einen `sha256`-Hash in der Richtlinie zu erlauben. Das würde +die Ursache beseitigen, verlangt aber einen Eingriff in die Inhaltsrichtlinie für etwas, das +nur eine Meldung in der Entwicklungskonsole ist — ein schlechter Tausch. + +**Geprüft wird das auf der Ebene der Quelle, nicht im Browser.** Ein e2e-Lauf kann es nicht +auffangen: React meldet den Unterschied nur im Entwicklungsmodus, der Testlauf nutzt den +Produktionsbau. Ein erster Versuch mit einer Konsolenprüfung im e2e war deshalb auch ohne den +Fix grün und wurde wieder entfernt — eine Prüfung, die nicht anschlägt, ist schlimmer als +keine. `web/tests/thema-vorab.test.ts` prüft stattdessen die drei Dinge am Skript, die +zusammenpassen müssen: Nonce, Hydrierungsausnahme und derselbe Speicherschlüssel wie im +Umschalter. diff --git a/web/app/layout.tsx b/web/app/layout.tsx index 3d25c85..0b36e3d 100644 --- a/web/app/layout.tsx +++ b/web/app/layout.tsx @@ -35,7 +35,26 @@ export default async function RootLayout({ children }: { children: React.ReactNo return ( -