/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: 'selector',
// ...
}
<!-- Dark mode not enabled -->
<html>
<body>
<!-- Will be white -->
<div class="bg-white dark:bg-black">
<!-- ... -->
</div>
</body>
</html>
<!-- Dark mode enabled -->
<html class="dark">
<body>
<!-- Will be black -->
<div class="bg-white dark:bg-black">
<!-- ... -->
</div>
</body>
</html>
기존 스타일에 하나하나 dark라는 프리픽스를 넣어주며 모드에 맞는 디자인을 해야합니다(노가다 시작)
tailwind.config.js의 colors에 셋팅해준 컬러 테마로 빠르게 작업해줍니다~
Next.js 프로젝트의 _document.tsx
파일에서 초기 로드 시 로컬 스토리지에서 다크 모드 설정을 가져와 HTML 태그의 클래스를 설정하는 스크립트를 추가했습니다.
import Document, { Html, Head, Main, NextScript } from 'next/document';
import Script from 'next/script';
class MyDocument extends Document {
render() {
return (
<Html lang="ko">
<Head>
<Script id="theme-init" strategy="beforeInteractive">
{`
(function() {
const rootElement = document.documentElement;
const colorMode = window.localStorage.getItem('color_mode') || 'light';
rootElement.className = colorMode;
})();
`}
</Script>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
페이지가 로드되기 전에 실행되어 로컬 스토리지에서 저장된 color_mode
값을 가져와 HTML 태그의 클래스를 설정합니다.
해당 스크립트가 없어도 모드 전환은 가능했지만 페이지 이동 시, DOM을 새로 그리는 경우, 예를들어 window.location.href
를 사용하여 이동하는 경우 초기화 되어서
스크립트로 init하는 과정이 필요했습니다.
Next.js에서 테마 초기 설정을 위해 beforeInteractive 전략을 사용하는 이유는 페이지가 로드되기 전에 사용자의 다크 모드 설정을 적용하기 위함입니다.
beforeInteractive는 페이지가 상호작용하기 전에 스크립트를 실행합니다.
다크 모드와 라이트 모드를 전환할 수 있는 ThemeToggle
컴포넌트를 만들었습니다.
import { useEffect, useState } from 'react';
const Toggle = ({ onClick, toggle }) => (
<button onClick={onClick}>
{toggle ? '다크' : '라이트'}
</button>
);
export default function ThemeToggle() {
const [colorMode, setColorMode] = useState('light');
useEffect(() => {
const storedColorMode = window.localStorage.getItem('color_mode') || 'light';
setColorMode(storedColorMode);
}, []);
const handleChangeMode = () => {
const htmlElement = document.querySelector('html');
if (!htmlElement) return;
const newColorMode = colorMode === 'light' ? 'dark' : 'light';
setColorMode(newColorMode);
htmlElement.className = newColorMode;
window.localStorage.setItem('color_mode', newColorMode);
};
return (
<div className="flex gap-1 py-5 border-b dark:border-dark-gray700 border-dark-gray300 justify-between items-center w-full cursor-pointer">
<p className="dark:text-dark-gray100 text-black text-sm">
다크 모드 전환
</p>
<Toggle onClick={handleChangeMode} toggle={colorMode === 'dark'} />
</div>
);
}
초기 로드 시 로컬 스토리지에서 저장된 모드를 가져와 colorMode
상태를 설정하고, 버튼 클릭 시 다크 모드와 라이트 모드를 전환합니다.
Next.js와 Tailwind CSS를 사용하여 다크 모드와 라이트 모드를 구현하는 방법을 알아보았습니다. ThemeToggle
컴포넌트를 통해 사용자는 쉽게 모드를 전환할 수 있으며, 로컬 스토리지를 사용하여 설정을 유지할 수 있습니다.