Next.js에서 현재 시간 렌더링은 조심하자
next.js
Next.js 서버 컴포넌트나 프리렌더 경로에서는 new Date(), Date.now()처럼 실행 시점마다 값이 달라지는 함수를 조심해야 한다.
특히 날짜를 "방금 전", "5분 전", "어제"처럼 현재 시간 기준으로 포맷팅하면 서버가 만든 HTML과 브라우저에서 hydrate할 때의 결과가 달라질 수 있다. Next.js 16에서는 이런 경우 Client Component 안의 현재 시간 접근을 프리렌더 오류로 잡아준다.
이번에는 게시글 카드에서 formatDate()가 내부적으로 Date.now()를 호출했고, 그 컴포넌트가 Client Component 경계 안에 있어서 문제가 됐다.
해결은 현재 시간 기반 렌더링을 별도 Client Component로 분리하고, 실제로 formatDate()를 호출하는 컴포넌트를 Suspense 아래에 두는 방식으로 했다.
typescript
export function PostTime({ time }: PostTimeProps) {
return (
<Suspense fallback={<time className="text-[13px]" dateTime={time} />}>
<PostTimeLabel time={time} />
</Suspense>
);
}
중요한 건 Suspense를 반환하는 컴포넌트 안에서 바로 formatDate()를 호출하면 안 된다는 점이다. formatDate()는 Suspense 아래의 하위 컴포넌트에서 실행되어야 한다.
정적 렌더링이 필요한 UI라면 절대 날짜로 표시하거나, 상대 시간이 꼭 필요하면 이렇게 동적 영역을 명확히 분리하는 편이 안전하다.