이슈 해결/Frontend

[Day.js] hydration error 로 시작해서 timezone으로 끝나다

씨씨상 2025. 1. 8. 15:08

 

 

이슈 파악 과정

 

 

서버 측에서 렌더링한 데이터와 클라이언트 측에서 렌더링하는 데이터가 다르면 다음과 같은 hydration error를 볼 수 있는데요.

제 경우에는 로컬에서 개발을 마친 후 테스트 서버, 실서버에 배포하면서 이 에러가 시작되었습니다.

 

 

처음에는 제 코드에 이상이 있는 줄 알고 코드를 이리저리 수정해 보았습니다만, 잘 생각해보니 로컬 환경에서는 멀쩡히 동작하는데 배포 환경에서만 이슈가 생기는 것이 이상했습니다.

또 코드를 만져보며 Day.js를 사용하지 않을 경우 에러가 나지 않는다는 것을 확인했기 때문에 저와 같은 현상을 겪은 사람은 없는지 검색해보았습니다.

다행히 금방 찾을 수 있었습니다. 고마워요 구글!

 

 

【Next.js】ブラウザのタイムゾーンを変えたら Hydration Error が起きた

export default function Page() { const datefmt = new Intl.DateTimeFormat('ja-JP', { year: 'numeric', month: '2-digit', day: '2-digit', timeZone: 'Asia/Tokyo', }); const created = datefmt.format(new Date('2024-02-08T00:00:00+09:00')).replace(/\//g, '-'); re

enuesaa.dev

 

 

 

생각을 달리 하기

 

 

위 블로그 글을 읽고 로컬에서 사용하는 시간대와 서버 시간대가 달라서 생기는 에러가 아닐까? 하는 가설을 세우고, Day.js의 timezone을 설정하는 방법을 찾아보며 코드를 수정했습니다.

코드로 직접 보는 것이 명확하겠죠? 제 기존 코드를 첨부합니다.

 

import dayjs from 'dayjs';

export type DatePiece = Date | null;
export const dayOnly = 'DD';
export const dateOnly = 'YYYY-MM-DD';
export const dateFull = 'YYYY-MM-DD HH:mm:ss';

export const formatDayOnly = (pDate: Date): string => {
  return dayjs(pDate).format(dayOnly);
};

export const formatDateOnly = (pDate: DatePiece): string => {
  return dayjs(pDate).format(dateOnly);
};

export const formatDateFull = (pDate: DatePiece): string => {
  return dayjs(pDate).format(dateFull);
};

 

이 상태에서 Day.js의 timezone과 utc 플러그인을 extend로 추가한 후, tz() 메서드로 변환하면 됩니다.

하단은 변경된 코드입니다.

 

import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';

dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.tz.setDefault('Asia/Seoul');

export type DatePiece = Date | null;
export const dayOnly = 'DD';
export const dateOnly = 'YYYY-MM-DD';
export const dateFull = 'YYYY-MM-DD HH:mm:ss';

export const formatDayOnly = (pDate: Date): string => {
  return dayjs(pDate).tz().format(dayOnly);
};

export const formatDateOnly = (pDate: DatePiece): string => {
  return dayjs(pDate).tz().format(dateOnly);
};

export const formatDateFull = (pDate: DatePiece): string => {
  return dayjs(pDate).tz().format(dateFull);
};

 

timezone 관련 설정을 더 찾아보니, dayjs.tz.setDefault() 메서드는 디폴트 timezone을 변경하는 것이 아니기에 재발 방지를 위해서는 로컬 환경에서도 프로덕션 타임존 설정을 더해줄 필요가 있습니다.

package.json 파일입니다.

 

"dev": "TZ=utc next dev"

 

이제 에러 없이 잘 동작하네요!

정말 많은 도움이 된 글을 출처로 첨부하니 비슷한 상황을 겪고 계신 분께 도움이 되길 바랍니다.

 

 

 

 

 

[출처]

Day.js 사용 시 주의사항

 

Dayjs 로 타임존을 다룰 때 주의해야 할 사항 2가지

Dayjs 로 타임존을 다룰 때 주의해야 할 사항들을 정리해본다.

velog.io

로컬 환경에서도 프로덕션 타임존 맞추기

 

React17から18へバージョンアップの奮闘記

バッジを贈って著者を応援しよう バッジを受け取った著者にはZennから現金やAmazonギフトカードが還元されます。 バッジを贈る

zenn.dev