Dark Mode with Tailwind CSS and Next.js
Posted at 24/01/2021
This quick little piece is to teach you how to implement in a very streamlined fashion dark mode in your website using Tailwind CSS and Next.js. Before getting it down, I was battling my brain out at trying to set up this. Especially with Next.js and all this server-side rendering stuff. Because of that, I was having trouble using your usual
local.storage for saving the preferred theme on the browser's cache.
I got a little overwhelmed because it seemed like a way much harder task, implementing dark mode than I could've ever hoped for. But after researching all articles around and asking for help late at night from my dev friends, I got to a very, very, simple setup using these two frameworks.
Basically, it all goes down to this library. It really does what it says it does: perfect dark mode in 2 lines of code. Easy peasy. Just install it at your project using any of these two:
This usage setup is also available in the next-themes documentation but I'll just copy it here for instructional's sake. The next step is going to your
_app.js file, which is created when setting up Next. Just wrap all of the elements in the return of your component function with the
ThemeProvider just like that:
It's so quick that this won't last more than two paragraphs too. Go to your
tailwind.config.js file and change the dark mode property to class, just like that:
You're done! Now, go back to the
_app.js file and just add as an attribute to the ThemeProvider a class value:
Setting up the toggle button
The last step is just setting a button up for toggling the themes whenever you want. We'll be using some of React's built-in features. It's simple, I promise you! Start by creating a
DarkModeButton.js in your components folder. It may look like this by now:
Now we're going to add two React Hooks. One for changing the theme itself, in charge of toggling between classes, and another for changing the icon displayed at the button whenever the light or dark theme is on. We're also going to use a Hook provided by the next-theme library. Don't forget to import these!
Then, we just have to create the button itself using the
<button> HTML tag at the return of the function. You can style it however you want by changing the utility classes. With Tailwind, to set how you want a given element to look like, when in the dark or light mode, just add the
dark prefix at the utility class, like:
When in light mode, the background color will be the gray-200, and when in dark mode it will be bg-black. Couldn't be easier :) This is the styling I've chosen for my button. It also includes the hover state.
Getting at the final steps, we just have to add an
onClick event to the button, passing to it the
setTheme hook we've previously declared in the function. And then, we can also use the mounted hook for changing the icons.
I'm using a sun and moon icon for representing light and dark themes. When in the dark theme, the sun icon is displayed indicating that, when clicking on it, the theme will change to the light one.
mounted hook is set at false by default, so your website will, at first load, be in light mode. If you want to change that, just swap it to true instead. You can also change the
<path> element to display different icons if you want it. The first
<path> rendered is the icon displayed when in the dark mode.
This implementation also avoids a common issue with dark mode which is the flashy-ness. This is a simple yet elegant way of doing it. Tailwind also makes it a lot easier for us to control how we want each element to look in a given theme. Instead of deciding which color, say your light gray color, goes to whenever the theme is dark, you can pinpoint in the exact component how it will render.
This is especially important since its dark mode isn't only getting colors to the opposite side of the light spectrum. Great dark mode implementations preserve the interface depth, still displaying how components, elements, and sections relate to each other in the desired hierarchy.
Hope you dig it! I wish I had found some article like this one when I was freaking about on how to do this. There you have it! For the night owl's eye health sake, dark mode.