@signap/signals-angular
@signap/signals-angular
Angular (standalone) wrapper for @signap/signals-web — a provideSignals()
provider plus an injectVisitorData() helper that mirror the React hook and Vue
composable.
Install
pnpm add @signap/signals-angular
# @angular/core and @angular/common are peerDependencies (>=17 <21)
Usage
Register the agent once with provideSignals() at bootstrap, then call
injectVisitorData() in any component below it.
Provider (app bootstrap)
// main.ts
import { bootstrapApplication } from "@angular/platform-browser";
import { provideSignals } from "@signap/signals-angular";
import { AppComponent } from "./app.component";
bootstrapApplication(AppComponent, {
providers: [
provideSignals({
apiKey: "pk_live_...",
endpoint: "https://ingest.signap.example",
}),
],
});
Consume (injectVisitorData)
// visitor-badge.component.ts
import { Component } from "@angular/core";
import { injectVisitorData } from "@signap/signals-angular";
@Component({
selector: "visitor-badge",
standalone: true,
template: `
@if (visitor.isLoading()) {
<p>Identifying…</p>
} @else if (visitor.error()) {
<p>Failed: {{ visitor.error()?.message }}</p>
} @else {
<p>visitor: {{ visitor.data()?.visitorId }}</p>
<p>confidence: {{ visitor.data()?.confidence }}</p>
<button (click)="visitor.refetch()">Re-identify</button>
}
`,
})
export class VisitorBadgeComponent {
// Field initializers run in the injection context, so injectVisitorData() is valid here.
readonly visitor = injectVisitorData({ tag: "page-view" });
}
Helper shape (v2)
injectVisitorData() runs agent.identify() once when the agent is ready and
exposes the resolved visitor as Angular signals. ADR §A2 means one
round-trip — no separate ack/lookup transition.
| field | type | when populated |
|---|---|---|
data |
Signal<IdentifyResult | undefined> |
once agent.identify() resolves |
isLoading |
Signal<boolean> |
true between call time and data |
error |
Signal<Error | null> |
last failure (load / identify) |
refetch |
() => Promise<void> |
re-run agent.identify() |
Read each signal by calling it (visitor.data()), in a template or a
computed/effect.
SSR-safe: provideSignals() gates SignalsAgent.load() behind
isPlatformBrowser(PLATFORM_ID), so it never runs during Angular Universal /
prerender server rendering.
Endpoint (required)
provideSignals() takes the underlying AgentLoadOptions. endpoint is
required — the published SDK ships no baked default host (the region→host map
is empty in this alpha), so pass an explicit endpoint (a string or a callback).
See the @signap/signals-web README (Endpoint section).
optsis snapshotted at bootstrap (later changes are ignored — re-bootstrap to swap apiKey/endpoint), the same contract as the React/Vue wrappers.
Why decorator-free
The package ships a functional provider, an inject() helper, and a plain class
wired through a DI factory — no @Injectable/@Component decorators. That keeps
it AOT-safe under a plain tsup build (no ng-packagr / partial-Ivy step needed)
and importable from any Angular 17+ app.