Nextjs에서 다크모드 구현하기
본 블로그는 next-themes(next-themes) + tailwindCSS를 사용하여 다크모드가 구현되어 있고, 그 방법이 매우 간편하여 소개하고자 한다.
next-themes
next-thems설치
$ npm install next-themes
or
$ yarn add next-themes
next-themes 사용
- Nextjs의 layout 파일에서 'use client'를 사용하고 있을 경우, 공식문서 그대로 컴포넌트를 ThemeProvider로 감싸주면 된다.
// layout.tsx
import { ThemeProvider } from 'next-themes'
function MyApp({ Component, pageProps }) {
return (
<ThemeProvider>
<Component {...pageProps} />
</ThemeProvider>
)
}
export default MyApp
- 만약 layout 파일이 csr이 아닐 경우, csr파일을 하나 만들어서 layout파일에서 사용한다.
// Provider.tsx
"use client"
import { ThemeProvider } from "next-themes"
const Providers = ({ children }: { children: React.ReactNode }) => {
return (
<ThemeProvider enableSystem={true} attribute="class">
{children}
</ThemeProvider>
)
}
export default Providers
- enableSystem 을 true로 설정하면 사용자 시스템 설정에 따라 theme이 설정된다.
- tailwndCSS의 클래스로 다크모드를 설정하기 위해, attribute는 "class"로 했다.
// layout.tsx
import Providers from './Provider'
...
export default async function RootLayout({children,}: { children: React.ReactNode }) {
const session = await getServerSession(authOptions);
return (
<html lang="en">
<body className={notoSansKr.className}>
<Providers>
...layout 코드
{children}
</Providers>
</body>
</html>
)
}
tailwindCSS 설정
- tailwind.config 파일에서 토글버튼을 사용하여 수동으로 테마 전환을 하기 위해 darkMode를 'class' 로 설정해준다.
// tailwind.config.js
module.exports = {
darkMode: 'class',
// ...
}
다크모드 토글 버튼 만들기
- useTheme() Hook을 사용하여 테마 정보를 가져온다.
- systemTheme: 시스템 테마, theme: 현재 테마, setTheme: 테마 상태 변경
- currentTheme을 따로두고 사용하는 이유는, 시스템 테마와 현재 테마가 다를 수 있기 때문이다.
- 최초설정을 시스템테마로 하였을 경우 theme(현재 테마)은 'light'나 'dark'가 아닌 'system'으로 되기 때문에, theme === 'dark' ? : 와 같이 분기처리하여 화면을 구현할 경우, 원하지 않는 결과가 나올 수 있기 때문이다.
"use client"
import { useTheme } from "next-themes"
export default function DarkModeBtn() {
const { systemTheme, theme, setTheme } = useTheme()
const currentTheme = theme === "system" ? systemTheme : theme
return (
<div>
<button
className="bg-pink-100 dark:bg-white flex items-center transition duration-300 focus:outline-none shadow"
onClick={() => {
setTheme( currentTheme === 'dark' ? 'light' : 'dark')
}}
>
{
currentTheme === 'dark' ?
<div>
...다크모드 버튼
</div>
:
<div
...라이트모드 버튼
</div>
}
</button>
</div>
)
}
다크모드 디자인 적용
tailwindCSS 공식 문서에서 나오 듯,
그냥 className에 'dark: ~~' 만 넣어주면, 다크모드에서의 디자인을 추가할 수 있다!
<nav className='bg-white dark:bg-gray-800 flex ...'>