Angular Islands
Angular hosts import the standalone Island component and use the <absolute-island> element in templates. Angular islands consume shared state through the injected IslandStore service.
#Authoring
Angular templates stay declarative. Import Island into the component and use <absolute-island> where you want the island.
TS
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { Island } from '@absolutejs/absolute/angular';
@Component({
imports: [CommonModule, Island],
selector: 'angular-host-page',
standalone: true,
template: '<absolute-island
' +
' component="ReactCounter"
' +
' framework="react"
' +
' hydrate="load"
' +
' [props]="{ initialCount: 0 }"
' +
'/>'
})
export class AngularHostComponent {}#Stores
Use the injected IslandStore service to read and subscribe to selectors from a shared island store. This keeps the state model store-first, not prop-key-first.
TS
import '@angular/compiler';
import {
ChangeDetectorRef,
Component,
inject,
Input,
OnDestroy,
OnInit,
signal
} from '@angular/core';
import { Subscription } from 'rxjs';
import { IslandStore } from '@absolutejs/absolute/angular';
import { counterIslandStore } from '../../islands/counterStore';
class AngularCounterImpl implements OnDestroy, OnInit {
static __absoluteProps = {
initialCount: 0,
label: ''
};
readonly changeDetectorRef = inject(ChangeDetectorRef);
readonly islandStore = inject(IslandStore);
readonly incrementSharedAction = this.islandStore.get(
counterIslandStore,
(state) => state.incrementShared
);
subscription = new Subscription();
initialCount = 0;
label = '';
readonly count = signal(this.initialCount);
readonly sharedCount = signal(0);
ngOnInit() {
this.count.set(this.initialCount);
this.subscription.add(
this.islandStore
.select(counterIslandStore, (state) => state.sharedCount)
.subscribe((value) => {
this.sharedCount.set(Number(value));
this.changeDetectorRef.detectChanges();
})
);
}
increment() {
this.count.update((value) => value + 1);
}
incrementShared() {
this.incrementSharedAction();
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
Component({
selector: 'abs-angular-counter',
standalone: true,
template: '<div>
' +
' <p>{{ label }}</p>
' +
' <strong>Local: {{ count() }}</strong>
' +
' <strong>Shared: {{ sharedCount() }}</strong>
' +
' <button (click)="increment()">Increment Angular</button>
' +
' <button (click)="incrementShared()">Increment Shared</button>
' +
'</div>'
})(AngularCounterImpl);
Input()(AngularCounterImpl.prototype, 'initialCount');
Input()(AngularCounterImpl.prototype, 'label');
export const AngularCounter = AngularCounterImpl;