Dark Mode in Next.js bauen – ohne das Aufblitzen

Dark Mode scheint einfach zu sein. Dann sieht man das Aufblitzen.

Wenn ein Nutzer Ihre Seite lädt, sendet der Server das Standard-Theme. Der Nutzer sieht für einen Sekundenbruchteil einen weißen Bildschirm, bevor das Dark-Theme aktiviert wird. Das ist eine schlechte User Experience.

Das Problem besteht darin, dass der Server localStorage nicht lesen kann. Der Server erfährt erst vom Theme, nachdem der Browser Ihr JavaScript ausgeführt hat.

So beheben Sie es.

Die Lösung: Das Inline-Script

Sie müssen das Theme anwenden, bevor React startet. Fügen Sie ein kleines Script in Ihren <head>-Tag ein. Dieses Script liest die Präferenz aus und fügt die dark-Klasse sofort hinzu.

Verwenden Sie diese Schritte:

  • Fügen Sie ein Script in den <head> Ihres RootLayout ein, um localStorage zu prüfen.
  • Verwenden Sie suppressHydrationWarning in Ihrem <html>-Tag. Dies verhindert, dass React sich über die Theme-Abweichung beschwert.
  • Verwenden Sie einen ThemeProvider, um den State zu verwalten und mit localStorage zu synchronisieren.
  • Verwenden Sie CSS-Variablen mit Tailwind für flüssige Farbübergänge.

Warum das funktioniert: Das Script wird ausgeführt, bevor die Seite gerendert wird. Es verhindert das visuelle Springen.

Umgang mit Bildern

Bilder benötigen oft unterschiedliche Versionen für Light- und Dark-Mode. Sie haben zwei Möglichkeiten:

  • CSS-Methode: Verwenden Sie display: none und display: block, um Bilder basierend auf der .dark-Klasse auszutauschen. Dies ist der schnellste Weg.
  • Client-Methode: Verwenden Sie eine Komponente, die das Theme prüft und die richtige Bildquelle auswählt.

Pro-Tipp für serverseitige Inhalte

Wenn der Server das Theme für Diagramme oder umfangreiche Inhalte kennen muss, verwenden Sie Cookies anstelle von localStorage.

  • Speichern Sie das Theme in einem Cookie.
  • Verwenden Sie Next.js Middleware, um dieses Cookie zu lesen.
  • Übergeben Sie das Theme über Header an Ihr Layout.

Dies ermöglicht es dem Server, von Anfang an das korrekte HTML zu senden.

Zusammenfassung für ein blitzfreies System: • Verwenden Sie ein Inline-Script im <head> • Verwenden Sie suppressHydrationWarning • Verwalten Sie den State mit einem Context Provider • Achten Sie auf Änderungen der Systemeinstellungen

Dieser Ansatz eignet sich für Produktionsanwendungen. Er gewährleistet sofortiges Umschalten und null Aufblitzen.

Quelle: https://dev.to/aon_infotech_3a1b6ff525fc/building-a-dark-mode-system-in-nextjs-app-router-without-layout-flash-5gf9