Creating dark mode is very easy with the help of next-themes package. If we take a look in the documentation it is very straightforward and easy to add.
make sure to install it first using npm:
copynpm install next-themes
or using yarn:
copyyarn add next-themes
Then simply add <ThemeProvider>
in _app.js
copy1import { ThemeProvider } from "next-themes"; 2 3function MyApp({ Component, pageProps }) { 4 return ( 5 <ThemeProvider> 6 <Component {...pageProps} /> 7 </ThemeProvider> 8 ); 9} 10 11export default MyApp;
To make the dark mode toggle we just need to use useTheme()
hooks inside our Next.js app.
copy1import { theme, useTheme } from "next-themes"; 2 3// somehwere inside page/component function return ... 4return ( 5 <div> 6 <button onClick={() => setTheme(theme == "dark" ? "light" : "dark")}> 7 Toggle DarkMode 8 </button> 9 </div> 10);
It's as simple as that. 😤
...
Further down the line, we can make our toggle button look prettier with some css touch to it.
First add Fontawesome. The simplest way is by using cdn and put it in the head inside _app.js.
copy1// _app.js 2import React from "react"; 3import Head from "next/head"; 4 5function MyApp({ Component, pageProps }) { 6 return ( 7 <React.Fragment> 8 <Head> 9 <link 10 rel="stylesheet" 11 href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" 12 crossOrigin="anonymous" 13 referrerPolicy="no-referrer" 14 /> 15 </Head> 16 <Component {...pageProps} /> 17 </React.Fragment> 18 ); 19} 20 21export default MyApp;
Then create <ToggleDarkModeButton />
component.
copy1// ToggleDarkModeButton.js 2import { useTheme } from "next-themes"; 3import css from "./index.module.css"; 4 5const ButtonToggleDarkMode = () => { 6 const { theme, setTheme } = useTheme(); 7 8 return ( 9 <div> 10 <input 11 type="checkbox" 12 className={css.checkbox} 13 onChange={() => setTheme(theme == "dark" ? "light" : "dark")} 14 checked={theme == "dark" ? true : false} 15 id="chk" 16 /> 17 <label className={css.label} htmlFor="chk"> 18 <i className={`fas fa-moon ${css.faMoon}`}></i> 19 <i className={`fas fa-sun ${css.faSun}`}></i> 20 <div className={css.ball}></div> 21 </label> 22 </div> 23 ); 24}; 25 26export default ButtonToggleDarkMode;
Lastly, create index.module.css for the component and paste the following
copy1.checkbox { 2 opacity: 0; 3 position: absolute; 4} 5 6.label { 7 background-color: #111; 8 border-radius: 50px; 9 cursor: pointer; 10 display: flex; 11 align-items: center; 12 justify-content: space-between; 13 padding: 5px; 14 position: relative; 15 height: 26px; 16 width: 50px; 17 /* transform: scale(1.5); */ 18} 19 20.label .ball { 21 background-color: #f3f4f6; 22 border-radius: 50%; 23 position: absolute; 24 top: 2px; 25 left: 2px; 26 height: 22px; 27 width: 22px; 28 transform: translateX(0px); 29 transition: transform 0.2s linear; 30} 31 32.checkbox:checked + .label .ball { 33 transform: translateX(24px); 34} 35 36.faMoon { 37 color: #f1c40f; 38} 39 40.faSun { 41 color: #f39c12; 42}
Congrats! Now you have a toggle button like so.