2026. 6. 17.

Next.js Hydration 오류, AI 코딩 초보가 3분 만에 볼 5가지

AI 코딩 도구가 만든 Next.js 화면에서 Hydration 오류가 뜨면 전체 코드를 다시 만들기보다 서버 출력과 브라우저 첫 출력이 달라지는 값부터 3분 안에 좁혀야 합니다.

4 min read
Next.js Hydration 오류, AI 코딩 초보가 3분 만에 볼 5가지 대표 이미지

Next.js 앱을 AI 코딩 도구로 만들었는데 브라우저 콘솔에 Hydration failed가 뜨면 화면 전체가 틀어진 것처럼 느껴집니다. 버튼이 늦게 살아나거나, 날짜와 테마가 바뀌거나, 첫 화면은 보이는데 새로고침할 때만 오류가 보이기도 합니다. 이때 바로 "전체 코드를 고쳐줘"라고 묻기보다, 서버가 처음 만든 HTML과 브라우저가 처음 그린 화면이 어디서 달라졌는지 3분 안에 좁히는 편이 안전합니다.

Next.js Hydration 오류를 서버 출력, 브라우저 출력, 동적 값 순서로 좁히는 작업 흐름

Hydration은 React가 서버에서 만들어진 HTML에 브라우저 이벤트와 상태를 붙이는 과정입니다. react.dev의 hydrateRoot 문서는 이때 클라이언트의 첫 렌더링 결과가 서버 HTML과 맞아야 한다고 설명합니다. nextjs.org의 hydration 오류 문서도 시간, 랜덤값, 브라우저 전용 API, 잘못된 HTML 구조처럼 처음 출력이 달라지는 요소를 주요 원인으로 다룹니다. 그래서 이 오류는 "React를 전부 모른다"는 뜻이 아니라, 첫 출력이 달라지는 값을 아직 분리하지 못했다는 신호에 가깝습니다.

첫 1분에는 오류 문장과 컴포넌트 이름만 찾습니다

브라우저 콘솔에서 제일 먼저 볼 것은 마지막 줄이 아니라 오류가 시작되는 문장입니다. Text content does not match server-rendered HTML, Hydration failed because the server rendered HTML didn't match the client, There was an error while hydrating 같은 문장이 보이면, 그 아래에 컴포넌트 스택이나 파일 경로가 붙어 있는지 확인합니다.

처음 1분 동안 복사할 것은 세 가지면 충분합니다.

  1. 콘솔의 첫 hydration 오류 문장
  2. 오류 아래에 나온 컴포넌트 이름이나 파일 경로
  3. 오류가 난 화면에서 바로 달라져 보이는 값

예를 들어 헤더에 현재 시각이 있고, 서버는 오전 10:02를 만들었는데 브라우저는 즉시 오전 10:03으로 그리면 첫 출력이 달라질 수 있습니다. 랜덤 추천 문구, 로그인 여부, 다크 모드, 장바구니 개수, window.innerWidth, localStorage 값도 같은 방식으로 문제를 만들 수 있습니다.

2분째에는 서버와 브라우저에서 달라지는 값을 표시합니다

AI에게 다시 묻기 전에 코드 안에서 "처음부터 달라질 수 있는 값"을 표시합니다. 아래 질문으로 빠르게 좁힙니다.

  • new Date()Date.now()가 JSX 안에서 바로 실행되는가
  • Math.random()으로 색상, 문구, id를 바로 만드는가
  • window, document, localStorage, sessionStorage를 렌더링 중에 읽는가
  • 브라우저 경로, 쿼리, 테마, 언어 값에 따라 첫 문장이 바뀌는가
  • HTML 태그가 잘못 중첩되어 브라우저가 DOM을 자동으로 고치는가

nextjs.org 문서는 클라이언트에서만 달라져야 하는 내용은 useEffect 이후에 처리하는 방법을 제시합니다. 핵심은 서버와 브라우저의 첫 화면을 일단 같게 만든 뒤, 브라우저에서만 알 수 있는 값은 마운트 이후에 바꾸는 것입니다.

"use client";

import { useEffect, useState } from "react";

export default function LocalTimeBadge() {
  const [label, setLabel] = useState("시간 확인 중");

  useEffect(() => {
    setLabel(new Date().toLocaleTimeString("ko-KR"));
  }, []);

  return <span>{label}</span>;
}

이 코드는 정답 템플릿이 아니라 방향 예시입니다. 서버와 브라우저가 처음에는 같은 시간 확인 중을 그리고, 실제 시간은 브라우저가 준비된 뒤에 넣습니다.

3분째에는 use client를 전체가 아니라 경계에만 붙입니다

초보자가 자주 하는 실수는 오류가 난 페이지 전체에 "use client"를 붙이는 것입니다. nextjs.org의 use client 문서는 이 지시어가 클라이언트 컴포넌트의 진입 경계를 선언한다고 설명합니다. 모든 파일에 붙일 필요가 없습니다.

좋은 순서는 이렇습니다.

  1. 오류가 난 가장 작은 컴포넌트를 찾습니다.
  2. 그 컴포넌트가 브라우저 API나 상태, 이벤트를 실제로 쓰는지 봅니다.
  3. 필요하면 그 작은 컴포넌트 파일에만 "use client"를 둡니다.
  4. 서버에서 가져올 수 있는 정적 문구, 제목, 본문, SEO 요소는 서버 컴포넌트에 남깁니다.

예를 들어 글 제목과 본문은 서버 컴포넌트에 남기고, 테마 토글 버튼이나 현재 시간 배지만 작은 클라이언트 컴포넌트로 분리하는 식입니다. 이렇게 하면 오류도 줄이고 페이지 구조도 덜 흔들립니다.

Hydration 오류를 AI에게 다시 물을 때 붙여야 할 4가지 정보 체크리스트

AI에게는 원인 후보와 최소 수정 범위를 함께 줍니다

AI 코딩 도구에 다시 물을 때는 "Hydration 오류 고쳐줘"보다 아래처럼 묻는 편이 낫습니다.

상황:
Next.js App Router 화면에서 hydration 오류가 납니다.

오류 문장:
[브라우저 콘솔의 첫 hydration 오류 문장]

관련 파일:
[오류 스택에 나온 컴포넌트 파일 경로]

달라질 수 있는 값:
[Date, Math.random, window, localStorage, 테마, 경로, 로그인 상태 중 의심되는 값]

요청:
서버 첫 출력과 브라우저 첫 출력이 달라지는 지점을 먼저 3가지 후보로 좁혀 주세요.
전체 페이지를 client component로 바꾸지 말고, 최소 수정으로 해결하는 패치를 제안해 주세요.
브라우저 전용 값이 필요하면 useEffect 이후로 옮기는 방식부터 검토해 주세요.

이 프롬프트는 AI가 코드를 새로 짜기 전에 원인을 좁히게 만듭니다. 특히 "전체 페이지를 client component로 바꾸지 말라"는 문장이 중요합니다. 오류 하나를 없애려고 페이지 전체 구조를 바꾸면 다음 배포나 SEO에서 다른 문제가 생길 수 있습니다.

suppressHydrationWarning은 마지막 표시용 도구로만 둡니다

react.dev와 nextjs.org 문서에는 suppressHydrationWarning도 나옵니다. 타임스탬프처럼 서버와 브라우저가 어쩔 수 없이 다르게 보일 수 있는 단일 요소에서 경고를 숨기는 방법입니다. 하지만 react.dev 문서는 이것이 탈출구이며 남용하지 말아야 한다고 설명합니다.

따라서 초보 단계에서는 이 순서로 판단합니다.

  1. 서버와 브라우저의 첫 출력이 같게 만들 수 있으면 먼저 그렇게 고칩니다.
  2. 브라우저에서만 가능한 값이면 useEffect 이후로 옮깁니다.
  3. 특정 컴포넌트만 클라이언트 경계가 필요하면 작게 분리합니다.
  4. 정말 표시 차이를 피할 수 없는 단일 텍스트에만 suppressHydrationWarning을 검토합니다.

환경 변수나 로그인 토큰처럼 민감한 값은 AI 채팅창에 그대로 붙이면 안 됩니다. 필요한 것은 값의 실제 내용이 아니라 "서버에서만 있는 값인지", "브라우저에서도 읽어야 하는 값인지", "첫 렌더링에 표시되는 값인지"입니다.

마지막으로 지금 할 일은 하나입니다. 콘솔의 첫 hydration 오류 문장, 관련 컴포넌트 파일, 처음부터 달라질 수 있는 값 하나를 적어서 AI에게 최소 수정 범위로 다시 묻습니다. 이 세 가지가 있으면 막연한 "화면이 이상해요"에서 벗어나, 실제로 고칠 수 있는 작은 문제로 바뀝니다.

참고 출처

다음으로 읽을 기사

같은 흐름으로 이어 읽기 좋은 기사만 추려 보여줍니다.

댓글 0

이 글을 읽은 독자들의 생각을 나눠보세요.

비밀번호(선택)

첫 번째 댓글을 남겨보세요

여러분의 생각이 다른 독자에게 도움이 됩니다.