38
loading...
This website collects cookies to deliver better user experience
Because Tailwind is so low-level, it never encourages you to design the same site twice. Even with the same color palette and sizing scale, it's easy to build the same component with a completely different look in the next project.
darkMode
key from false
to 'class'
in tailwind.config.js
file.
module.exports = {
darkMode: 'class',
// ...
}
_app.js
file to check if dark mode is applied or not before mounting the actual component to the DOM. For that, we will use useEffect
from react just before returning the component._app.js
:import '../styles/globals.css';
import { useEffect } from 'react';
function MyApp({ Component, pageProps }) {
useEffect(() => {
if (
localStorage.theme === 'dark' ||
(!('theme' in localStorage) &&
window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
//check if there is any key for theme in local storage and if the system color theme is dark
document.documentElement.classList.remove('light'); //OPTIONAL - remove light from the html document if any
document.documentElement.classList.add('dark'); // add dark to the <html></html> itself as <html class='dark'></html>
} else {
document.documentElement.classList.remove('dark'); // remove dark from the html document if any
document.documentElement.classList.add('light'); //OPTIONAL - add light to the <html></html> itself as <html class='light'></html>
}
},[]);
return <Component {...pageProps} />;
}
export default MyApp;
ThemeSwitch.jsx
:import { useEffect, useState } from 'react';
const isDark = () => //Function that will return boolean if any of the condition is satisfied
(localStorage && localStorage.theme === 'dark') || //Condition 1 - has local storage and theme = dark in local storage is found
(!('theme' in localStorage) &&
window.matchMedia('(prefers-color-scheme: dark)').matches); //Condition 2 - No theme key in local storage but media color scheme is dark
const getTheme = (isDark) => (isDark ? 'dark' : 'light'); //Function to return 'dark' or 'light' string
const ThemeSwitch = () => {
const [darkMode, setDarkMode] = useState(false); //State for holding theme status
const toggleMode = () => { //onClick handler for changing theme on button press
localStorage.theme = getTheme(!darkMode); //setting up local storage theme value
if (localStorage.theme === 'dark') { // If theme is 'dark'
document.documentElement.classList.remove('light'); // remove 'light' from html class
document.documentElement.classList.add('dark'); // add 'dark' to html class
} else { // if not 'dark'
document.documentElement.classList.remove('dark'); // remove 'dark' from html class
document.documentElement.classList.add('light'); //add 'light' to html class
}
setDarkMode(!darkMode); //set dark mode state to opposite of initial value
};
useEffect(() => {
setDarkMode(isDark()); //before page mount set the value of dark mode by observing theme in local storage
}, []);
const darkModeActive =
process.browser && document.documentElement.classList.contains('dark'); // returns true if its a client and 'dark' is present in html
// process.browser is deprecated can be written as typeof window === 'undefined'
return (
<>
<button className='w-10 h-10 focus:outline-none' onClick={toggleMode}>
<span className='sr-only'>Color mode switch button</span>
{darkModeActive ? ( //switch mode icon according to html class 'dark' or 'light'
// Light Icon Svg
) : (
// Dark Icon Svg
)}
</button>
</>
);
};
export default ThemeSwitch;
dark:some-value
in the class names if you want manual control over CSS.