본문 바로가기
프로그래밍/Node.js

Node.js Prefers-color-scheme 서버에서 처리하는 방법

by 꾸션 2022. 7. 22.

서버사이드(Server side)에서 사용자의 Color scheme를 미리 알고, 처리할 수 있는 방법을 공유합니다.

 

Mac, iPhone과 같은 경우 이미 오래전부터 "다크테마"라는 것을 제공하고 있습니다. 눈의 피로도를 줄이고, 전력소모를 줄일 수 있기 때문입니다. 이 방법은 이미 Windows, Linux, Android와 같은 많은 OS기반 기기에저 채택되어 널리 사용되고 있습니다.

이에 따라 웹페이지나 앱화면에서 다크테마를 제공하고 있습니다.

사용자가 시스템에서 설정한 테마에 따라서 웹, 앱 화면의 컬러색상이 자동으로 바뀌고, 혹은 버튼과 같은 사용자 액션에 따라서 선택할 수 있도록 제공하는 서비스가 많아지고 있습니다.

이와 같은 처리를 클라이언트 사이드 최종 웹 혹은 앱화면에서 처리하지 않고, 서버사이드에서 미리 파악하고 이를 바로 클라이트화면에 적용할 때 사용할 수 있는 방법을 공유합니다.

 

아래의 예제는 Node.js서버로 유명한 Express를 예제로 설명합니다.

 

사용자에게 컬러스키마(color scheme)를 요청

app.get("/", (req, res) => {
  res.set("Accept-CH", "Sec-CH-Prefers-Color-Scheme")
  res.set("Critical-CH", "Sec-CH-Prefers-Color-Scheme")
  res.set("Vary", "Sec-CH-Prefers-Color-Scheme")

  let colorScheme = req.get("sec-ch-prefers-color-scheme")
  
  res.render('index', { colorScheme: colorScheme })
});

 

응답헤더에 "Accept-CH", Critical-CH" 그리고 "Vary"를 세팅을 하면 아래와 같이 클라이언트와 패킷을 한 번더 주고 받음으로써, 원하는 데이터를 받을 수 있습니다. ("*-CH"에서 "CH"는 Client Hint라는 뜻입니다.)

HTTP/2 200 OK
Content-Type: text/html
Accept-CH: Sec-CH-Prefers-Color-Scheme
Critical-CH: Sec-CH-Prefers-Color-Scheme
Vary: Sec-CH-Prefers-Color-Scheme
GET / HTTP/2
Host: chance.dev
Sec-CH-Prefers-Color-Scheme: "dark"

 

최종 클라이언트화면에서는 아래와 같이 처리할 수 있습니다.

 

방법1: HTML에서 최종 처리

<!DOCTYPE html>
<html>
<head>
  <%- colorScheme === 'dark' ? '<link rel="stylesheet" href="/css/dark.css" />' : '<link rel="stylesheet" href="/css/light.css" />' %>
</head>
<body>
</body>
</html>

 

방법2: HTML과 CSS로 분기 처리

HTML

<!DOCTYPE html>
<html data-color-scheme="${colorScheme || "system"}>
<head>
</head>
<body>
</body>
</html>

CSS

:root {
  --color-body-text: #000;
  --color-body-background: #fff;
}

:root[data-color-scheme="dark"] {
  --color-body-text: #fff;
  --color-body-background: #000;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-color-scheme="light"]) {
    --color-body-text: #fff;
    --color-body-background: #000;
  }
}

html,
body {
  background: var(--color-body-background);
  color: var(--color-body-text);
}

 

급하게 적어서 다소 이해가 어려울 수 있습니다.

다음에 시간이 될 때 좀 더 알아보기 쉽게 수정하겠습니다.

반응형

댓글