
Join the Conversation!
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
"Please login to view comments"
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
Complete source code available till this point of lesson is available at
By logging in, you'll unlock full access to this and other free tutorials on JSM Pro.
Why? Logging in lets us personalize your learning experience, track your progress, and keep you in the loop with new workshops, coding tips, and platform updates.
You'll also be the first to know about upcoming launches, events, and exclusive discounts.
No spam—just helpful content to level up your skills.
If that sounds fair, go ahead and log in to continue →
Enter your name and email to get instant access
##Looks like we found a thief monkey By the way, I liked the trick how you reached till here. You have a good sense of humor. You will improve a lot if you join our course with this passion.
var
(function-scoped, outdated)let
(block-scoped, modern and recommended)const
(block-scoped, cannot be reassigned)_
, or $
let let = 5;
is invalid)myVar
and myvar
are different)string
, number
, boolean
, null
, undefined
, bigint
, symbol
Objects
, Arrays
, Functions
Subscribing gives you access to a brief, insightful summary of each lecture to stay on track.
00:00:02 You know how I said that some of our classes in the globals.css will cover both the light and the dark mode.
00:00:09 So, what do you say that we go ahead and implement the light and dark mode switch right away?
00:00:15 So that way we can start testing both modes right from the start of developing our application.
00:00:20 To implement dark mode within our application, we'll use the most widely used package for that purpose, NextThemes.
00:00:28 Next Themes has about 5,000 stars, which is always important when you're searching for well-maintained packages, that they're popular and actually used
00:00:36 in production.
00:00:37 In this case, as they say, it'll give you perfect Next.js dark mode in two lines of code.
00:00:43 and it supports system preferences or any other theme with no flashing.
00:00:48 If you go to their example, you can see that we have system, dark, and this, oh, oh no, light.
00:00:54 So let's implement this so that we no longer have to stare at this light screen.
00:00:58 First things first, I'll run npm install next-themes.
00:01:02 If you try installing it, it just won't work.
00:01:05 And sometimes when you're following along some projects and an error happens, you can be discouraged.
00:01:11 I totally get that.
00:01:12 But in this course, I want to actually teach you how we would go about fixing it.
00:01:16 This happens because there's conflicts in the version of React we're using with the version of Next Themes.
00:01:22 Basically, a version mismatch.
00:01:24 To fix this, what I would usually do is run force or legacy peer depths, which is a better approach.
00:01:32 But in this case, I wouldn't recommend this approach.
00:01:35 Let me tell you why.
00:01:37 Sooner or later, the next themes package, which right now supports only React 16, 17, and 18, will get updated to support the latest version of React.
00:01:47 So instead of just downgrading our React to a lower version, which would cause another set of problems, we can tell next themes that we want to use the
00:01:56 React version that we have right now.
00:01:58 To do that, we can head over to our package.json, scroll down below the dev dependencies, and add a new option, which is going to be called package manager.
00:02:09 And here, we can say npm version 10.7.0. After that, you can give it overrides.
00:02:17 And under Overrides, you can say React and say that we want to use the version of React that we're currently using.
00:02:24 And you can do that by saying $react.
00:02:27 And I'll repeat the same thing for React-DOM and React-DOM here.
00:02:33 So this way, all of our packages will follow these versions of React.
00:02:37 Now, after saving the package JSON, try to install NextThemes again by running npm install NextThemes.
00:02:45 And immediately, it got installed.
00:02:47 After installing, we'll set a theme provider that'll wrap the whole application and allow us to access the next theme-specific properties,
00:02:55 like mode, across any part of our application.
00:02:57 Specifically, it's a global context API.
00:03:00 So let's create a new folder called context in the root of our application, outside of the app folder, call it context, and within it,
00:03:08 create a new file called theme.tsx.
00:03:12 Within here, you can run RAFCE to quickly create a functional component.
00:03:17 But in this case, this component will be a provider.
00:03:20 So let's rename theme to theme provider.
00:03:25 And every provider's job is to basically wrap the component and then return whatever is passed into them through children.
00:03:32 And we can also pass all of the other props that we get.
00:03:36 In this case, we have to define the types for this component.
00:03:39 So let's say type will be theme provider props coming from next themes.
00:03:46 You can see that the next theme package was nice enough to provide us with all of the TypeScript interfaces for using their package.
00:03:54 Many new packages nowadays will do that, just so you don't have to write the types yourself.
00:03:58 Then, right within it, you can wrap everything in a next themes.
00:04:04 Provider, like this, give it access to all the props that will pass into it, and then within it, just render the children.
00:04:12 Basically, what you're doing is nothing.
00:04:14 You're saying, I will wrap this entire thing with the provider and allow me to access some of the props, which will allow me to check whether we're looking
00:04:23 at the light or dark mode.
00:04:24 Now, where is this NextThemesProvider coming from?
00:04:27 We can import it, ThemeProvider, as NextThemeProvider, coming from NextThemes, like this.
00:04:34 Finally, since we're using props, children, and some other client-side functionalities here, we'll have to turn this into a UseClient directive.
00:04:42 Finally, we actually want to put it to use.
00:04:45 So let's head over to our app-layout.tsx, you know, where we wrap everything, because whatever you wrap here, it'll be present across the entire application
00:04:56 and all the files, which is exactly what we want to do in this case.
00:05:00 And here we can wrap the children with the theme provider we just created, coming from add forward slash context, next themes,
00:05:08 like this.
00:05:08 And to it, we need to pass a couple of props.
00:05:11 The first one is attribute is equal to class.
00:05:15 Now, how can you know what this means?
00:05:17 Well, first of all, you can hover over it and then see that this is an HTML attribute modified based on the active theme.
00:05:24 It accepts class and then data, meaning any data attribute, like data mode, data color, and so on.
00:05:30 For more info though, you can visit the theme provider GitHub page and see what each one of these properties does.
00:05:37 The default theme system simply says the default theme name.
00:05:41 The attribute data theme modifies the attributes based on the active theme.
00:05:46 Disable transition on change optionally disables all CSS transitions when switching themes.
00:05:51 In this case, we'll also have to provide it a default theme, which I'll set to system, so it'll automatically recognize our system settings.
00:06:00 We can say enable system as well, and finally disable transition on change.
00:06:06 If you go back to your browser and reload, you'll see that we have one error.
00:06:10 I'll explain how to fix it soon.
00:06:11 But first, notice that my specific website changed to dark mode because of my system preferences.
00:06:19 On your Windows, Linux, or MacOS device, if you have selected dark as the system preference, then the website will be dark.
00:06:27 Otherwise, it'll be light.
00:06:28 But let's quickly see what this error is about.
00:06:31 It is a hydration error.
00:06:33 It's happening because the next theme tries to update elements after they're pre-rendered on the server and sent to the browser for hydration.
00:06:41 Basically, the HTML created on the server is sent to the browser.
00:06:46 But as soon as it is loaded in the browser, the next theme updates elements, resulting in a different HTML skeleton.
00:06:54 This is what a hydration mismatch is.
00:06:57 To fix this issue, which is really not an issue, NextTheme recommends suppressing hydration warnings.
00:07:03 And don't worry, because suppressing hydration warnings will not suppress hydration warnings that you may later cause in your app.
00:07:10 It will only suppress hydration warnings at one level deep, so we're good.
00:07:14 Only this one coming from next theme.
00:07:17 So going back to your code where you have the HTML, you can say suppress hydration warning, and I'll save it.
00:07:25 Now if you go back and reload, we have a nice dark mode or a light mode, whatever you prefer.