Dark Mode Persistence with Next.js is Harder than with plain React (MUI example)

Dark Mode Persistence with Next.js is Harder than with plain React (MUI example)


Dark Mode Persistence with Next.js is Harder than with plain React (MUI example)

Consider subscribing to see mo tutorials on how I built BuzzRank.io with Next.js and Firebase!

Step-by-step tutorial: https://medium.com/@luca_79189/how-to
Finished project on GitHub: https://github.com/DiMatteoL/buzzrank
Link to BuzzRank: https://www.buzzrank.io

📚 Chapters
00:00 - Persistent Dark Modes in Next.js are not as simple as they seem
00:08 - How Persistent Dark Modes work for React apps
00:15 - Why Persistent Dark Modes are flickering in Next.js apps
00:34 - How to fix the Dark Mode Flicker in Next.js apps
00:57 - Tutorial: Persistent Dark Modes with Next.js and MUI
01:18 - Get a runnable Next.js app (here with MUI)
01:49 - Use next-themes ThemeProvider to set your page’s data-theme
02:27 - Update the theme from our app with the useTheme React hook
02:48 - Dynamically change MUI’s theme
03:12 - Final result: A deployed app with persistant light and dark modes


🎶 Music
On My Way by Ghostrifter Official | https://soundcloud.com/ghostrifter-of
Music promoted by https://www.chosic.com/free-music/all/
Creative Commons CC BY-SA 3.0
https://creativecommons.org/licenses/

#Nextjs #MUI #DarkMode


Content

0.08 -> Implementing a persistent  dark mode in your Next.js app, 
3.12 -> easy enough right? Well it's not that simple and here is why. 
7.04 -> The way to make a dark mode persistent  is usually to store a "theme" value in  
10.72 -> your clients local storage and count  on them to render their own theme. 
14.4 -> But with Next you render React pages on the  server, so if you take the same approach you might  
19.28 -> end up facing the dreaded "Dark Mode Flicker". Here's johnny. 
24.4 -> Yeah that's right, major websites like the home  page for Material UI or Chakra UI suffer from  
29.68 -> this problem and although it's not the worst  problem, it still accounts for a bad user  
33.84 -> experience, so let's see how to fix it. Well the server side rendered page is  
38.16 -> displayed on the client before the theme can be  updated so we don't have too many options here: 
42.96 -> We need to add a script to our pre-built HTML  pages to prevent them from being displayed  
47.68 -> until the local storage theme value has been  read and the css variables have been updated  
52.16 -> and only then can the page be displayed. There's a library called next-themes  
56 -> that can do this for us. Now that we know how it works  
58.4 -> let's see how to do it in practice and how I've  implemented it with Material UI in my own project  
63.52 -> BuzzRank. If you don't use Material UI  don't worry the logic will be the same. 
67.52 -> For those who want to follow along see the  step-by-step link in the description and for  
72.16 -> those who want to see the finished project I've  also added a link to the public GitHub repository. 
76.8 -> Alright let's get going. From the Material UI GitHub repository,  
80.24 -> copy the instructions on the "Next.js with  TypeScript" example and paste it in your terminal.  
85.04 -> And then run "npm install". At that point we have a  
87.76 -> Next.js with Material UI project. Now let's clean it up a little. 
91.6 -> With most JavaScript UI libraries you'll  have a ThemeProvider in your "_app.tsx" file. 
96.8 -> You want to move it to another component  that we'll call "PageProvider" under  
100.4 -> the "src" folder so that at the end your  _app.tsx and PageProvider look like this. 
105.76 -> Feel free to pause the  video if you need more time. 
108.16 -> Now that we've done this  let's implement our dark mode. 
110.96 -> Let's start by installing the library called  "next-themes" then add the ThemeProvider from  
116 -> next-themes to the root of your app  component. This provider prevents the  
119.52 -> display of the page as long as the HTML  "data-theme" value hasn't been updated. 
123.76 -> Here it is set to light by default. And  now we just want to set our css "color" and  
128.32 -> "background-color" depending on the "data-theme". With MUI you can do this with the "GlobalStyles"  
133.44 -> component to which we can  give a light background for  
136.08 -> light mode and a dark background for dark mode. To make sure this works properly we can go back  
140.32 -> to our project and switch the "data-theme" from  light to dark here you can see that the background  
144.8 -> and the text are properly changing colors. To do that from the app we have access to  
148.64 -> the "useTheme" React hook that i will call from  the pages/index.tsx file. It gives us access to  
154.96 -> the current theme and to a method to change it. And by pairing them with the button we now have  
159.76 -> an app that can change themes, persist  them, and never flickers on reloads. 
164.4 -> As you can see here, if i change  the page the theme is persisted. 
168.48 -> So, that would be the end if we didn't use  Material UI but since we use it, we also need  
173.12 -> to inform it that the theme has been changed. If we go into our "theme" file into our "src"  
177.84 -> directory we can see that we only have one  theme at the moment and we want to create two,  
182.24 -> one for light and one for dark. And we also want to go back  
184.8 -> to our page provider and update the  theme accordingly using React hooks. 
188.96 -> Alright I took the time to make the app  a little prettier and I deployed it to  
192.8 -> Vercel and here is the final result. If you want to check it for yourself,  
196.72 -> the link is in the description. And that's how you get a persistent  
199.84 -> dark mode using Next.js and Material UI. This video is part of a tutorial series on  
204.8 -> how i built buzzRank.io with Next.js and Firebase  so if you're interested in those tools or want  
210.4 -> to know the story of how i built buzzRank, you  know what to do, subscribe, it would also mean  
215.2 -> the world to me. See ya

Source: https://www.youtube.com/watch?v=kIkdoW6VUIQ