此錯誤表示在水合過程中,Angular 預期看到伺服器端渲染時所渲染並加上標註的 DOM 結構,但用戶端的 DOM 樹與伺服器渲染出的 DOM 樹不同。
這通常是因為使用瀏覽器原生 API 直接操作 DOM,改變了 Angular 產出之外的 DOM 結構。使用 innerHTML 或 outerHTML 設定 HTML 內容也會發生此錯誤,因為這同樣會改變 Angular 產出之外的 DOM 結構。解決方式是重構元件,改用 Angular 的 API 而非原生 API。若確實無法做到,可以在元件的宿主節點加上 ngSkipHydration 屬性,停用該元件及其子元件的水合。ngSkipHydration 只應作為最後手段,並應視為需要修正的錯誤。
更多關於水合的資訊,請見本指南。
以下範例會觸發此錯誤。
@Component({
selector: 'app-example',
template: '<div><span>world</span></div>',
})
export class Example {
hostElement = inject(ElementRef).nativeElement;
ngOnInit() {
// Create a new <p> element with the `Hello` text inside
const newNode = document.createElement('p');
newNode.innerHTML = 'Hello';
// Insert the <p> before the first element. Since Angular has no information
// about the <p> element, it will be looking for the <div> element at the first
// element position instead. As a result, a hydration mismatch error would be
// thrown. Instead, update component's template to create the <p> element.
this.hostElement.insertBefore(newNode, this.hostElement.firstChild);
}
}
除錯方式
開發者主控台中的錯誤訊息應包含造成問題的應用程式 DOM 結構特定部分的資訊。請檢查該部分的應用程式是否有與水合相關的錯誤,例如使用原生 API 直接操作 DOM。
請確認你的範本具有有效的 HTML 結構。更多資訊請見水合指南。
你可以把 ngSkipHydration 屬性加到元件宿主節點,作為可能的暫時解法。
如果你的應用程式在開發環境中運作正常,但在生產建置中出現水合錯誤,請確認交付給瀏覽器的 HTML 含有 Angular 在伺服器上渲染時產生的註解節點。這些註解節點會被 Angular 執行時期用作檢視容器的錨點(無論是否使用水合),水合過程也預期它們出現在原本的位置。如果你有自訂邏輯會移除伺服器端渲染產生的 HTML 中的註解節點,或已設定 CDN 在提供內容前移除它們,請停用註解節點的移除功能,並檢查水合錯誤是否消失。
常見原因
CDN 功能或瀏覽器擴充功能也可能在水合開始前變更來自伺服器的 HTML。這時你可能只在生產環境中看到這個錯誤,或只收到部分使用者的錯誤。請閱讀水合指南中的 CDN 與瀏覽器擴充功能。