먼저 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
'웹 > 프론트엔드' 카테고리의 다른 글
[Next.js] App Router에서 Client Component하위에 Server Component렌더링하기 (4) | 2024.10.27 |
---|---|
Next.js + jest 설정 시 react/swiper 해석이 안되는 이슈 (0) | 2024.04.22 |
[Next.js] Next/Image layout:fill과 sizes에 대해 (0) | 2024.03.18 |
[Next.js] NextJS Boilerplate 제작기 (1) | 2024.03.07 |
[Babylon.js] Gimzo, GimzoManager를 pub/sub 패턴으로 관리하기 (0) | 2023.06.25 |
댓글