Next.js Dark Mode with No Flicker + Tailwind CSS

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
let's look at how to allow users to toggle between light and dark mode in nextjs and why it's more challenging than it [Music] seems hello and welcome I'm Dave today I'll show you how I allow users to choose between light and dark mode on my nextjs blog and I'll provide links to all resources in the description below I'll also provide a link for you to join my Discord server where you can discuss web development with other students and you can ask questions that I can answer and receive help from other viewers too I look forward to seeing you there applying light and dark mode to your website with Tailwind CSS isn't too difficult you just identify the system preference and then that is what is applied however if you want to allow your users to toggle between light and dark mode it gets a little more complicated in nextjs and that's because everything is rendered on the server first and there's no way the server knows the individual users preferences for light or dark mode you have to wait until you load the site in the browser to read those from local storage what can happen the problem you could have is a flash or a flicker of light because you might be loading in the light mode from the server render and yet the user's preference is dark or vice versa so how to handle that well I found a package or dependency if you will that will help you it's called Next themes let me show you how I applied it to my nextjs blog we're in vs and you want to add one line to your Tailwind config file you can see that line is dark mode and then has a value of class and that tells Tailwind we're going to manually change between light and dark modes after making that change let's go to the package Json file and you can see that I have added next themes as a dependency in my blog now to do that in your blog let's go ahead and open up the terminal you can see I've typed it out already but it's npmi next- themes to install this in your your project so go ahead and do that and press enter now after adding next themes we want to go inside of our app directory where our page our root page and root layout is and let's go ahead and create a providers. TSX I'm going to press alt Z to wrap this down so we can see it all but what I'm going to do is create a client component then I'm going to import theme Provider from next themes and then I'm going to export the function providers and this function is going to have children passed in now children is a react. react node type then we're going to return the theme provider that is wrapped around the children and we want to set a few attributes so we have attribute equals class and then default theme equals system because that's what we'll load in first is the system preference then you want to click or not click but you want to add enable system as well so all three of those go with the theme provider now I'm going to provide all of this code in a link in the description as well after creating the provids file go to your layout file your root layout file and you want to import providers at the top so you can see I'm importing providers right here inside of my blog and then we need to scroll past all of the different metadata that I have and I've got a little bit of code commented out from another tutorial that you would find on my blog about the Google tag manager and how to add Google analytics but for this we're just looking at providers that I put right inside of the body element and then I wrapped it around my Navar and my main element and then you see the children passed inside of the main element but the key here is to wrap providers around all of this now there is a misunderstanding about providers and context themes essentially being used so let's go ahead and look at the nextjs docs okay I'm in the nextjs docs and we're under using context providers what I want to highlight here is a pattern essentially because it says context providers are typically rendered near the root of an application to share global concerns like a theme and that's exactly what we're doing and it says since react context is not supported in server components if you try to create a context at the root of your application it causes an error that's all true so the misunderstanding here is that you can't use these without making your entire application a client side application but you can let's go ahead and look at the rest of this so it says to fix create your context and render its provider inside of a client component that's exactly what we did so we created a client component with our provider and then it says your server component will now be able to directly render your provider since it's been marked as a client component so now with the provider rendered at the root all other client components throughout your app will be able to consume the context so by putting that provider at the RO you're not making your entire application a client component so I just wanted to clear that up as we add this to the application now before we leave the layout component there's one other thing we should look at let me press alt Z to wrap this code down you can see I'm using the suppress hydration warning attribute let's look at the react docs for this now we're in the react docs if you use serers side react rendering normally there's a warning when the server and the client render different content well that's what we're going to get with next themes because the server cannot know what I want for my light or dark mode preference so next themes is going to grab that throw that class onto the HTML element that's going to conflict with what the server sent they won't match so we'll get that mismatch well that's what this suppress hydration warning attribute is all about so it says if you set this to True react will not warn you about mismatches in the attributes and the content of that element but it only only works one level deep so that's good you're not switching this for your entire application and is intended to be used as an escape hatch and that's exactly what we need here because the server can in no way render my preference or your preference for light and dark mode so it says don't overuse it but this is a great use for this attribute we're back in vs code now I'm going to scroll to my components directory and inside of there I created a component called theme switch you can see that it's a component this is the component that's going to allow me to click on the sun or moon icon and switch the themes on my blog so you can see I'm bringing in the Sun and Moon icons I'm also bringing in use State and use effect bringing in the use theme Hook from next themes and bringing in the image component from nextjs so let's look inside this component the very first thing I need to do is check to see if the component is mounted in the client or not so I have used state for our mounted State mount mounted and set mounted I'm only going to check that inside of use effect because use effect will only run in the client so therefore when use effect runs I'll know the component is mounted so we're going to set mounted to True inside of the use effect so we won have an error beforehand when it does the initial render on the server so we also say if we're not mounted this is where we return the image component now this image component has a placeholder image for me to avoid content layout shift so when it's replaced by the sun or moon icon that I really want you don't see that shift of the icons in my navbar now the source for this is a base 64 image and I'll wrap this down you see a very long line here now when you follow the link to the source code in the description feel free to copy this placeholder image out if you want to again it's a base 64 SVG image right here now after this and here's all the settings for that image then we just check the result resolved theme value that comes from the used theme hook we're getting a set theme function and a resolved theme value we're checking that and then we're setting the appropriate onclick method and the appropriate icon either the Sun or the moon if I'm in dark mode I want to see the sun icon when I click on it I want it to set the theme to light so again for all these code examples I've got a link in the description and the end result here is a nextjs website that identifies your system preference at first before the user has essentially selected a their own preference but then after that selection is set it does set this inside of the local storage if you want to check for light and dark mode you'll see it there but after it is set it's always going to grab that value and throw that class on the HTML element it does cause that hydration warning the mismatch but we're suppressing that because this is an instance where we actually want that to happen and we know know what value we want on there so you're left with a site that identifies the user preference without a flash now notice uh next themes the documentation says you may see a flash in Dev mode but in production next theme says you will not see a Flash and I have not I've deployed this to my live blog if you want to see an example of that as well that's also where all the code samples for this tutorial are and I'll link to that in the description remember to keep striving for Progress over Perfection and a little progress every day will go a very long way please give this video a like if it's helped you and thank you for watching and subscribing you're helping my channel grow have a great day and let's write more code together very soon
Info
Channel: Dave Gray
Views: 11,415
Rating: undefined out of 5
Keywords: next.js dark mode, dark mode nextjs, next js dark mode flicker, next js dark mode tailwind, nextjs, next.js, dark mode, dark mode toggle, no flicker, no flash, nextjs dark mode, nextjs dark mode toggle, next.js dark mode toggle, light and dark mode, light and dark mode toggle, light and dark theme, tailwind, tailwind css, tailwindcss, dark mode next.js, next.js 14, nextjs 14, light dark nextjs, dark light switch, dark toggle, dark mode nextjs tailwind, light dark mode nextjs
Id: 7zqI4qMDdg8
Channel Id: undefined
Length: 9min 42sec (582 seconds)
Published: Fri Dec 15 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.