angular / angular/angular

SSR/Prerendering + Hydration for document fragments

Open
#67,785 8 comments 1 reaction 0 assignees View on GitHub
area: core core: hydration feature gemini-triaged
Dominant language
TypeScript
Stars
101k
Forks
27.5k
Avg merge
1d 19h
Merged PRs (30d)
288

Description

### Which @angular/* package(s) are relevant/related to the feature request?

core

### Description

## Overview

I'd like to be able to use Angular components in [Astro islands](https://docs.astro.build/en/concepts/islands/) with Angular's client hydration.

This is not currently possible today, because Angular expects to control the entire document during hydration.
It looks for an `` comment node as the first child of the body, and throws an exception if this is not present.

## Details

With Astro islands, the component is pre-rendered with a DOM structure similar to this:

```html




Some page title


...






```

To perform hydration, Astro expects a "framework integration" to provide a function that takes this `` element, the component definition, and original input properties.

Today, I am using the `@analogjs/astro-angular` package to perform this task. This performs hydration by throwing away the existing DOM and rerendering the component from scratch. https://github.com/analogjs/analog/blob/beta/packages/astro-angular/src/client.ts#L26

> Side note: it also currently does pre-rendering with Angular's `renderApplication`, which produces an entire document on its own. See https://github.com/withastro/roadmap/discussions/1322

## Initial Attempt

I have tried enabling client hydration with the Analog integration, by adding the `provideClientHydration` providers [here](https://github.com/analogjs/analog/blob/beta/packages/astro-angular/src/client.ts#L22) and [here](https://github.com/analogjs/analog/blob/beta/packages/astro-angular/src/server.ts#L100).

This produces a DOM structure like this:

```html




Some page title


...





{"__nghData__":[...]}

```

When Angular is doing client hydration, it looks for `` as the first child in the body, but throws because it's not there, assuming the DOM it originally rendered had been modified.

### Proposed solution

The ask of this feature is to support hydration for fragments of the document, where Angular is given a containing element (the island), and treats that as the document body.

This would allow Analog to leverage Angular's client-side hydration, and reuse the DOM that is in place from prerendering.

I am imagining an API similar to this:

```ts
export const appConfig: ApplicationConfig = {
providers: [
provideBrowserGlobalErrorListeners(),
provideClientHydration(withEventReplay()),
/* NEW: */ provideClientHydrationHost(htmlElement),
]
};
```

The `htmlElement` would be the `` component I described above.

This would "scope" the hydration to just its host element container. This provider would only be present on the client.

I'm also thinking that `@angular/platform-server` could provide a function similar to `renderApplication`, but produces 2 parts instead of the whole document: the body content, and the head content. This would allow an app rendering islands to more easily control how that content gets inserted into the DOM.

```ts
const { body, head } = renderApplicationParts(bootstrap);
```

### Alternatives considered

An alternative is to throw away the existing DOM as Analog does today.

Analog could also mess with the `` node and put it somewhere that Angular is "happy" with, but that couples it to internal implementation details, and falls apart when there is more than one island on the page.

Contributor guide

Open the contributing guide

Research direction

Start by tracing Angular's provideClientHydration and renderApplication entry points, then review the linked Analog client.ts and server.ts integration. Compare the current whole-document assumptions with the proposed island host and renderApplicationParts APIs. Done means the requested fragment hydration and body/head rendering behavior is supported without discarding prerendered DOM.

Written by the indexing model from the issue text.

Assessment

Tech stack
angular, typescript
Domain
frontend, web-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.