profile

Diary Of A Dev

#3: Adding dark mode to your page has never been this easier.

Published about 2 months ago • 4 min read

Hello Devs,

Nowadays, one feature that you will see in almost all sites specially in blogs is theme switching specifically dark mode.

And that's what we are building today. [Dark Mode in NextJs page with Tailwind and Shadcn-UI]

So, let's dive in to build our third frontend feature.

What are we building?

Live preview with code: https://stackblitz.com/edit/stackblitz-starters-adalin?file=app%2Fpage.tsx

Philosophy.

First, let's understand the philosophy and basic system design behind adding dark mode to a web page.

As frontend engineers we should provide our users the best experience possible. Readability and simplicity are extremely important. There is no point in creating the best animation in the world which leaves your user confused.

Remember, The goal is to be clear not clever.

Dark mode provides relief to user's eyes. You yourself as a developer must be using dark theme of VS-Code. Then why deprive your users from that experience.

System Design.

You must have seen the color wheel.

Color wheel provides a complimentary color for each primary color. You will use the color wheel if you are building multiple themes on your page.

But for our purpose we only care about two colors white (primary) and black (secondary). I have oversimplified the design by saying white (primary) and black (secondary) colors.

Actually we will be using different shades of those colors using hue and saturation as you will see later.

We will predefine all our primary and their respective secondary colors and whenever user switches to dark mode all we have to do is switch the primary and secondary colors being used in our code.

Let the coding begin.

Let's start by creating a new NextJs project using create-next-app. Create-next-app is equivalent to create-react-app but for NextJs.

npx create-next-app@latest nextDark --typescript --tailwind

This will create a new NextJs project named `nextDark` with typescript and tailwind already configured for us. Now replace the default content in `app/page.tsx` with the following code.

page.tsx is a special file in NextJs which serves as home page.

The button you see in above code is not a regular button it is a shadcn-ui component. Shadcn is a UI components library. Let's add it to our project.

Run the following two commands in your terminal. Run them one by one.

npx shadcn-ui@latest init // answer few config questions, go with default ones.

npx shadcn-ui@latest add button

The first command installs shadcn-ui, its dependencies latest version. Sets up the project configuration like tailwind.config.ts and `app/globals.css`.

The second command add the button component in `components/ui/button.tsx`.

Ok, our home page is ready to go.

See the globals.css file, it is modified by shadcn-ui. It contains some interesting configurations.

The class `.dark` defines secondary color for each respective primary color. Check the global css file and explore the primary and their secondary colors for a while. This makes our job to switch to light/dark mode very easy.

Adding dark mode.

Install `next-themes`. Next-themes provides a wrapper to wrap the part of application where we want theme switching. We will wrap our entire application.

npm install next-themes

Create theme provider (the wrapper). Create a new file `theme-provider.tsx` and paste the following code.

Make sure to add "use client" at top of the file because this must be a client component not server component. Then we import ThemeProvider from "next-themes" and return it with children.

Next let's wrap the root layout with ThemeProvider. `app/layout.tsx` is again a special file in NextJs. The style and content in layout is applied to the entire app.

So, wrapping layout with ThemeProvider will add theme-switching to the entire app.

Okay, now all we need to do is add a theme toggle button. Notice in the above code there is a component `<ModeToggle />`. Let's create that component and we will be done.

The above code adds a dropdown menu to switch between light, dark, and system. The dropdown is a shadcn-ui component. So let's add that component to our project.

Run the following command.

npx shadcn-ui@latest add dropdown-menu

This will add dropdown-menu component in `component/ui/dropdown-menu.tsx`.

Break down of few important things in mode-toggle.jsx:

  • setTheme sets the theme (light, dark, or system) in the provider so that it is accessible to entire app.
  • The tailwindCSS of Sun and Moon elements.
    • Sun (scale-100 dark:scale-0): Sun icon width becomes 0 when theme is dark so that it is not visible in dark mode.
    • Moon (scale-0 dark:scale-100): Moon icon width becomes 100% when theme is dark so that is is visible in dark mode.
    • And vice versa.

Cool, now go ahead and try to switch the theme.

Congrats!

Oh wait, what? It is not working. Ya, it won't work because we have a little bug.

Gotcha

Right now the theme switching won't work because of a small bug.

See we are using `tsx` and `jsx` both in our application. But NextJs was initiated with typescript configurations so tailwind ignores our jsx files. Just add the js and jsx in tailwind config.

And that is it.

Now our theme switching is working perfectly fine. You can check the final project at the preview link provided at top.


Your users are gonna love you for giving them a dark mode.

Reply to this email, if you have any suggestion on which feature should I build next.


Whenever you are ready, I can help you in 2 ways.

  • Ask Me Anything: If you have any question related to web development. Ask me here. I reply to all questions.
  • LinkedIn For Developers: Book 1:1 call with me to turn around your LinkedIn profile and attract better opportunities.

Diary Of A Dev

Become better F.E developer in 10 minutes a week.

I am building one complex frontend feature or solving a complex frontend interview question every week. And breakdown the exact steps, thought process, and system design behind it. Join the newsletter to learn with me.

Read more from Diary Of A Dev

Hello Devs! Welcome back to another Tuesday of building a frontend feature. Today we are solving a very commonly asked Interactive JS feature in an interview setup. [An interactive pie chart]. This one is going to be a quick issue as there isn't many moving parts to this question. What are we building? Live preview with code: https://stackblitz.com/edit/vitejs-vite-psytzb?file=index.html Philosophy Here the task is to create a range slider and a pie chart and bind the `pie chart` value with...

about 1 month ago • 1 min read

Hello Devs, The feature we are building today is frequently asked in React interviews. But it doesn't test only your React skills, it test your overall JavaScript and basic logic building skills. So, let's dive into building our fourth frontend feature: [Folder/File explorer UI] What are we building? Live preview with code: https://stackblitz.com/edit/vitejs-vite-4bqecn?file=src%2FApp.jsx Philosophy The basic philosophy behind building a "Folder/File explorer UI" is as following: List all the...

about 2 months ago • 3 min read
password strength indicator screenshot

Howdy Devs, Las week we built an `Adaptive progress bar text`. Despite the complexity of that feature, I am thrilled to see the response from you all on my first issue. Thanks a lot for that. Today we are building a simple "Password Strength Indicator" in React. So, let's dive in to build our second frontend feature. [Password Strength Indicator] What are we building? Live Preview: https://stackblitz.com/edit/vitejs-vite-usrrut?file=src%2FApp.jsx Let the coding began. If you have built...

2 months ago • 2 min read
Share this post