이 오류는 하이드레이션 중에 Angular가 서버 사이드 렌더링에서 렌더링하고 주석을 추가한 DOM 구조를 예상했지만, 클라이언트의 DOM 트리가 서버에서 렌더링한 DOM 트리와 달랐다는 뜻입니다.
이 오류는 보통 브라우저 네이티브 API로 DOM을 직접 조작하여 Angular가 생성한 DOM 구조를 외부에서 변경했을 때 발생합니다. 마찬가지로 innerHTML이나 outerHTML로 HTML 콘텐츠를 설정하여 Angular가 생성한 DOM 구조를 변경해도 발생합니다. 네이티브 API 대신 Angular가 제공하는 API를 사용하도록 컴포넌트를 리팩토링하면 해결할 수 있습니다. 이것이 불가능하다면 컴포넌트의 호스트 노드에 ngSkipHydration 속성을 추가하여 해당 컴포넌트와 자식 컴포넌트의 하이드레이션을 비활성화할 수 있습니다. ngSkipHydration은 최후의 수단으로만 사용해야 하며, 이를 사용하는 상태는 수정이 필요한 버그로 간주해야 합니다.
하이드레이션에 대한 자세한 내용은 이 가이드를 참고하세요.
다음 예제에서는 이 오류가 발생합니다.
@Component({
selector: 'app-example',
template: '<div><span>world</span></div>',
})
export class Example {
hostElement = inject(ElementRef).nativeElement;
ngOnInit() {
// `Hello` 텍스트가 들어 있는 새 <p> 엘리먼트를 생성합니다.
const newNode = document.createElement('p');
newNode.innerHTML = 'Hello';
// 첫 번째 엘리먼트 앞에 <p>를 삽입합니다. Angular에는 <p> 엘리먼트에 대한
// 정보가 없으므로 첫 번째 엘리먼트 위치에서 <div> 엘리먼트를 찾습니다.
// 따라서 하이드레이션 불일치 오류가 발생합니다.
// 대신 컴포넌트 템플릿을 수정하여 <p> 엘리먼트를 생성하세요.
this.hostElement.insertBefore(newNode, this.hostElement.firstChild);
}
}
오류 디버깅
개발자 콘솔의 오류 메시지에는 애플리케이션 DOM 구조에서 문제를 일으키는 특정 부분에 대한 정보가 포함됩니다. 해당 부분에 네이티브 API를 이용한 직접 DOM 조작 같은 하이드레이션 관련 오류가 있는지 살펴보세요.
템플릿의 HTML 구조가 유효한지 확인하세요. 자세한 내용은 하이드레이션 가이드를 참고하세요.
임시 해결 방법으로 컴포넌트 호스트 노드에 ngSkipHydration 속성을 추가할 수 있습니다.
개발 환경에서는 애플리케이션이 동작하지만 프로덕션 빌드에서 하이드레이션 오류가 발생한다면 브라우저에 전달하는 HTML에 서버 렌더링 중 Angular가 생성한 주석 노드가 포함되어 있는지 확인하세요. Angular 런타임은 하이드레이션 사용 여부와 관계없이 이 주석 노드를 뷰 컨테이너의 기준점으로 사용하며, 하이드레이션 과정에서도 주석 노드가 원래 위치에 있어야 합니다. 서버 사이드 렌더링으로 생성한 HTML에서 주석 노드를 제거하는 커스텀 로직이 있거나 CDN이 콘텐츠를 제공하기 전에 주석 노드를 제거하도록 설정했다면, 주석 노드 제거를 비활성화하고 하이드레이션 오류가 사라지는지 확인하세요.
일반적인 원인
CDN 기능이나 브라우저 확장 프로그램도 하이드레이션이 시작되기 전에 서버에서 받은 HTML을 변경할 수 있습니다. 이 경우 프로덕션에서만 오류가 발생하거나 일부 사용자에게서만 오류가 보고될 수 있습니다. 하이드레이션 가이드의 CDN과 브라우저 확장 프로그램을 참고하세요.