skip to content

In Angular hydration, what does the ngSkipHydration attribute do, where may you place it, and what does using it cost?

level: middleimportance: should knowfreq 45%

answer

  1. opt one subtree out
  2. component host only
  3. name checked, value ignored
  4. destroy and re-render

basics

~10 s

ngSkipHydration makes Angular skip hydrating one component and its children, which then re-render from scratch on the client. It is allowed only on a component host element and costs hydration's benefits in that subtree.

solid answer

~40 s

`ngSkipHydration` is a last-resort switch for a component that breaks hydration, usually through direct DOM manipulation. Put it on the component's host element in a template (`<app-chart ngSkipHydration />`) or in the component's `host` metadata. Angular then leaves that subtree out of hydration: the server still renders it, but on the client the component and its children are destroyed and rendered again, while the rest of the page hydrates. On any other element Angular throws NG0504. Only the attribute's name is checked, so `ngSkipHydration="false"` still skips. The cost is a local full re-render with possible flicker, and on the root component it disables hydration for the whole app. Fix the component and remove the attribute when you can.

code

ts · 18 lines
ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-chart',
  template: `<div class="canvas"></div>`,
  host: { ngSkipHydration: 'true' },
})
export class Chart {}

@Component({
  selector: 'app-dashboard',
  imports: [Chart],
  template: `
    <h1>Sales</h1>
    <app-chart />
  `,
})
export class Dashboard {}

go deeper

for a junior

Recall that ngSkipHydration turns hydration off for one component subtree and that it goes on the component's host element.

for a middle

Explain what happens to the skipped subtree on the client, the NG0504 placement rule, and why the attribute's value is ignored.

for a senior

Scope the attribute to the smallest wrapper component, track each use as debt, and judge the flicker it adds against fixing the component.

for a principal

Set a policy for when opting out is acceptable and how skipped components are tracked, so hydration does not erode one attribute at a time.

## What ngSkipHydration does `ngSkipHydration` is a special attribute that tells Angular's hydration to **leave one component subtree out**. On the client, that component and all of its children behave as if hydration were not enabled: the server-rendered DOM for that subtree is removed and the component renders itself again from scratch. The rest of the page still hydrates normally. It is meant for components that break hydration, typically because they (or a library they wrap) change the DOM with native APIs, and that cannot be fixed yet. ## Where it can go There are exactly two supported ways to put it on a **component host element**: ```html <app-chart ngSkipHydration /> ``` ```ts @Component({ selector: 'app-chart', template: `<div #canvas></div>`, host: { ngSkipHydration: 'true' }, }) export class Chart {} ``` Placement rules: - Only component host nodes qualify. On a plain element such as `<div ngSkipHydration>`, or through a directive's `host` metadata on a non-component element, Angular throws **NG0504**. - It is read as a **static attribute**, and only its name is checked. `ngSkipHydration="false"` still skips hydration; to stop skipping, remove the attribute. - Putting it on the root component effectively disables hydration for the whole application. ## What it costs | Aspect | Hydrated component | Component with `ngSkipHydration` | | --- | --- | --- | | Server HTML | Rendered and kept | Rendered, then replaced on the client | | Client work | Match and reuse DOM | Destroy and re-create DOM | | Visual effect | Stable | Possible flicker or layout shift in that area | | Mismatch errors inside it | Reported | Avoided, because nothing is matched | So the attribute trades hydration's benefits, in that one subtree, for correctness. A skipped subtree near the top of the page, or one that wraps most of the content, gives back most of what hydration was bought for. ## When to reach for it 1. **First, fix the component.** Replace native DOM calls with template constructs, or move DOM work that only makes sense in the browser until after rendering. 2. **If a third-party library needs to own its DOM**, and you cannot change it, wrap it in a small component and put `ngSkipHydration` on that wrapper only. 3. **Track it as debt.** Each attribute marks a component that does not hydrate; list them so they are removed once the underlying code is fixed. ## A worked example A dashboard embeds a charting library that builds its own SVG inside the component. Hydration fails with NG0500 inside the chart. The team: 1. confirms in development mode that the error points at the chart component; 2. wraps the library in a small `Chart` component whose template holds only the mount point; 3. adds `host: { ngSkipHydration: 'true' }` to that wrapper, not to the dashboard; 4. files a follow-up to render the chart after hydration or replace the library. The dashboard's headings, filters and tables still hydrate; only the chart area is rebuilt on the client. ## Common misunderstandings - It does **not** stop the component from rendering on the server; the server output is still produced and then replaced. - It does **not** make the mismatch go away elsewhere: a component that changes DOM outside its own host can still break its neighbours. - It is **not** an incremental-hydration trigger; it switches hydration off for the subtree rather than postponing it. ## Summary `ngSkipHydration` is a last-resort switch on a component host, with a name-only check and a real rendering cost. Interviewers ask about it to see whether a candidate treats it as a workaround with a price, rather than as the standard fix for every NG0500-family error.

  • Why does <div ngSkipHydration> fail?
    The attribute is valid only on component host nodes. On a plain element, or through a directive's host metadata on a non-component element, Angular throws NG0504. Move it to the host of the component that owns the problematic DOM.
  • Does ngSkipHydration stop the component from rendering on the server?
    No. The server still renders it, so the first paint includes its HTML. Only the client behaviour changes: that subtree is not matched against the server DOM and is rendered again from scratch.

saying these in an interview costs you the question

  • ngSkipHydration can be put on any element, such as a wrapping div
  • ngSkipHydration="false" re-enables hydration for that component
  • A skipped component is not rendered on the server at all
  • ngSkipHydration is the standard fix for every hydration mismatch
  • Skipping hydration postpones it until the component is visible