개인 토이 프로젝트로 nextjs 14버전 App router를 사용하여 개인 blog 개발을 시작하였다.
항상 쓰던 styled-components를 쓰지 않고 처음으로 써보는 css 프레임워크인 tailwind를 사용하여 개발 중에 dark theme 적용을 하려는데 styled-components와 달라도 너무 많이 달랐다.
nextjs + tailwind에서 dark theme을 적용하려면 몇가지 단계가 필요하다.
우선 nextjs에서 지원하는 ThemeProvider를 RootLayout에 body 자식을 감싸야한다.
하지만 provider는 client에서만 실행하게 해야해서 바로는 적용할 수 없고 children을 받는 custom provider를 생성한다.
//layout.tsx
'use client';
import { TProps } from '@/types/global';
import { ThemeProvider } from 'next-themes';
const CustomThemeProvider = ({ children }: TProps) => {
return <ThemeProvider attribute={'class'}>{children}</ThemeProvider>;
};
export default CustomThemeProvider;
그런 후 RootLayout에 body 자식node를 감싼다.
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="ko">
<body>
<CustomThemeProvider>
<Header />
<Profile />
{children}
<Footer />
</CustomThemeProvider>
</body>
</html>
);
}
위에서 ThemeProvider의 attribute는 class인데 이 부분이 tailwind에서 설정할 darkMode의 설정과 연결된다고 한다.
그런 후 global css에
//globals.css
:root {
--primaryColor: #7e91b4;
--secondaryColor: #ecdec5;
--accentColor: #385fad;
--textColor: #120d02;
--backgroundColor1: #ffffff;
--backgroundColor2: #ededed;
--backgroundColor3: #d9d9d9;
--ibm-plex-sans-kr: IBM Plex Sans KR, IBM Plex Sans;
}
:root.dark {
--primaryColor: #4b5e81;
--secondaryColor: #3a2d13;
--accentColor: #5279c7;
--textColor: #fdf8ed;
--backgroundColor1: #000000;
--backgroundColor2: #121212;
--backgroundColor3: #252525;
--ibm-plex-sans-kr: IBM Plex Sans KR, IBM Plex Sans;
}
위와 같이 설정을한다 :root는 light theme에 관한 색상을 지정하고,
:root.dark에는 dark theme에 관한 색상을 지정한다.
// tailwind.config.ts
theme: {
extend: {
colors: {
primaryColor: 'var(--primaryColor)',
secondaryColor: 'var(--secondaryColor)',
accentColor: 'var(--accentColor)',
textColor: 'var(--textColor)',
backgroundColor1: 'var(--backgroundColor1)',
backgroundColor2: 'var(--backgroundColor2)',
backgroundColor3: 'var(--backgroundColor3)',
},
},
},
global에 적용한 css 변수를 사용하여 각 컬러프로퍼티에 키로 지정해주면 세팅은 끝나게 된다.
그런 후 useTheme() 이라는 nextjs에서 지원하는 훅을 사용하여 theme의 상태롤 관리한다. useTheme을 사용하면 전역 상태 관리할 필요없이 html의 class와 color-scheme가 dark 또는 light로 변경되며 global css의 :root.dark or :root가 지정되며 theme이 바뀌게 된다.