Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:
오류가 발생했다.
이 오류는 서버에서 렌더링한 HTML와 클라이언트가 그린 HTML이 달라졌을 때 발생한다.
Next.js의 SSR 흐름은 아래와 같다.
문제가 발생한 코드를 보니
<p className="text-gray-600">
{new Date(comment.createdAt).toLocaleString()}
<p>
이 부분이었다.
toLocaleString()
은 브라우저 환경이나 언어 설정에 따라 결과가 달라질 수 있다.
SSR
서버에서는 Node.js
의 지역 설정에 따라 렌더링하고new Date().toLocaleString();
// 브라우저가 한국이면 → "2025. 5. 23. 오후 3:10"
// 브라우저가 미국이면 → "5/23/2025, 3:10 PM"
// 서버(Node.js)는? → 서버 OS의 기본 설정 따라감
나는 date-fns
라이브러리를 사용해서, 서버와 클라이언트에서 같은 포맷을 사용하도록 해결했다.
<p className="text-gray-600">
{formatRelativeTime(new Date(comment.createdAt))}
</p>
formatRelativeTime
유틸 함수import { format, formatDistanceToNowStrict } from "date-fns";
import { ko } from "date-fns/locale";
export function formatRelativeTime(date: Date) {
const now = new Date();
const diffInMs = now.getTime() - date.getTime();
const diffInSec = diffInMs / 1000; // 1000ms 여서
const diffInDay = diffInMs / (1000 * 60 * 60 * 24);
if (diffInSec < 60) {
return "방금 전";
}
if (diffInDay < 3) {
return formatDistanceToNowStrict(date, { locale: ko, addSuffix: true });
}
return format(date, "yyyy.MM.dd");
}
date-fns
라이브러리의 formatDistanceToNowStrict
을 사용해서 포맷을 맞췄다.
formatDistanceToNowStrict(date, { locale: ko, addSuffix: true })
지금(new Date()
)과 주어진 date
사이의 거리를 단위별(초, 분, 시간, 일..)로 엄격하게 계산해서 "1분 전", "3시간 전"과 같은 문자열을 리턴하는 함수이다.
locale: ko
→ 강제로 한국어 출력addSuffix: true
→ "전", "후" 같은 접미사 붙이기Next.js의 하이브리드 렌더링 구조에서 자주 발생하는 이슈라고 한다.
첫 데모 프로젝트에서 하이브리드 이슈를 해결하면서, SSR이 어떻게 동작하는지 하나씩 체감하는 중