웹/프론트엔드
Next.js 14 + tailwind에서 다크모드 설정하기
이민훈
2024. 10. 3. 00:17
먼저 tailwind.config.js에서 darkMode 설정을 해줍니다.
// tailwind.config.js
import type { Config } from "tailwindcss";
const config: Config = {
darkMode: ["class"],
content: [
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
extend: {
colors: {
background: "var(--background)",
foreground: "var(--foreground)",
},
},
},
plugins: [],
};
export default config;
그런 다음 cookie에서 현재 theme을 가져와 body의 class에 추가해 줍니다.
localStorage를 쓰지 않는 이유는 서버 환경에서 브라우저의 localStorage에 접근할 수 없기 때문입니다.
// layout.tsx
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const theme = cookies().get("theme")?.value ?? "light";
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased ${theme}`}
>
{children}
</body>
</html>
);
}
theme을 변경할 수 있는 버튼도 하나 있어야겠죠?
Cookie에 theme을 저장하고, 실시간 반영을 위해 body classList를 바로 변경해 줍니다.
"use client";
import { useCallback } from "react";
export default function ThemeChanger() {
const handleThemeChange = useCallback(() => {
const theme = document.cookie.includes("theme=light") ? "dark" : "light";
document.cookie = `theme=${theme}; path=/`;
document.body.classList.toggle("dark");
}, []);
return (
<button className="bg-slate-100" onClick={handleThemeChange}>
Change Theme
</button>
);
}
이제 다크모드가 잘 작동하는지 확인해 봅시다.
import ThemeChanger from "./theme-changer";
export default function Home() {
return (
<div className="flex flex-col p-8 w-60 gap-4">
<ThemeChanger />
<span className="text-black dark:text-red-500">Hello, World!</span>
</div>
);
}
https://github.com/Lee-Minhoon/blog-examples/tree/main/nextjs-dark-mode