錯誤百科

水合節點不相符

此錯誤表示在水合過程中,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 與瀏覽器擴充功能。