Symbol
Next.js 다크모드 구현하기 [next.js@14.1.0 + app directory + styled-components + next-themes]
next-themes 라이브러리를 사용하여 다크모드를 구현하는 방법에 대해 설명합니다.
2024-03-01
이번 포스팅에선 next.js 앱에 다크모드를 구현한 과정에 대해 정리하겠습니다.

다크모드란?

사용자 인터페이스에서 밝은 화면에 검은 글자 대신 어두운 화면에 흰 글자를 제공하는 테마로
사용자로 하여금 눈의 피로도를 낮추기 위해 서비스에서 제공하는 옵션입니다.
최근에는 라이트모드와 다크모드 둘중에 어떤게 눈건강에 더 나쁜가 라는 주제로 이런저런 의견들이 논쟁중이지만
다크모드를 선호하는 유저의 수는 유의미하게 많기 때문에 서비스제공자는 다크모드를 추가해서 나쁠게 없다는 생각입니다.

개발 환경

사용한 라이브러리들은 아래와 같습니다.
  • next@14.1.0 (app directory)
  • styled-components@6.1.8
  • next-themes@0.2.1

next-themes

next-themes next.js 환경에서 theme 변경을 지원하는 라이브러리 입니다.
작성일 기준으로 주간 다운로드수가 지속적으로 성장하고 있어 신뢰하고 채택했습니다.

ThemeProvider

next-themes 를 사용하려면 라이브러리에서 제공하는 ThemeProvider 컴포넌트로 전체 앱을 감싸야 합니다.
layout.tsx 파일이 Client 컴포넌트 라면 ThemeProvider 를 가공없이 바로 사용할 수 있지만
server 컴포넌트라면 아래 코드처럼 use client 환경에서 가공하는 과정을 거쳐야 합니다.
src/styles/ThemeProvider.tsx

위 코드에서 ThemeStyle 컴포넌트는 각 테마별 CSS변수를 저장한 styled-components 파일입니다.
src/styles/ThemeStyle.ts

src/app/layout.tsx

StyledComponentsRegistry 컴포넌트는 next.js 앱에 styled-components 라이브러리를 사용하기 위해 필요한 것으로 관련 내용은 여기를 참고하시기 바랍니다.

useTheme

이제 next-themes 에서 제공하는 useTheme 훅을 사용하여 현재 테마정보를 담은 resolvedTheme 와 테마를 변경할 수 있는 setTheme 함수를 사용할 수 있습니다.
아래는 theme를 스위칭 할 수 있는 ThemeSwitcher 컴포넌트 입니다.
src/components/ThemeSwitcher.tsx

사용자가 사이트의 테마를 변경할때 next-themes 는 그 정보를 로컬 스토리지에 저장하기 때문에 isClient 를 사용하여 클라이언트 사이드에서 렌더링 되도록 구현했습니다.

styled-components 에서 CSS변수 사용

styled-components에서 각테마에 할당한 CSS변수를 사용하는 예제입니다.
CSS의 변수를 사용할 땐 var() 내장 함수를 사용합니다.
transition속성은 테마를 변경할때 CSS가 부드럽게 전환되도록 해줍니다.
src/styles/GlobalStyle.ts

- 끝 -