Angular wiring
Install (substitute the target repo's own package manager — see invariant 3):
npm install @idhub/identity-core @idhub/identity-adapter-angular \
@idhub/identity-provider-segment @idhub/identity-provider-launchdarkly @idhub/identity-provider-fullstory
Drop any provider line the user did not select in step 2. If none were
selected, install @idhub/identity-core @idhub/identity-adapter-angular only
and pass providers: [] to forRoot() below.
AppModule — register IdentityModule.forRoot()
Write-if-absent for the IdentityModule.forRoot() block specifically — if
app.module.ts already exists (it almost always will), report the exact
imports: [...] insertion point rather than rewriting the file, and add only
this entry:
// app.module.ts
import { NgModule } from '@angular/core'
import { IdentityModule } from '@idhub/identity-adapter-angular'
// Import only the providers the user selected in step 2:
import { segmentProvider } from '@idhub/identity-provider-segment'
import { launchDarklyProvider } from '@idhub/identity-provider-launchdarkly'
import { fullStoryProvider } from '@idhub/identity-provider-fullstory'
@NgModule({
imports: [
IdentityModule.forRoot({
providers: [
// one entry per selected provider only — see references/provider-env-vars.md
segmentProvider({ client: analytics, writeKey: environment.segmentWriteKey }),
launchDarklyProvider({ clientSideId: environment.launchDarklyClientId }),
fullStoryProvider({ orgId: environment.fullStoryOrgId }),
],
cookie: { name: '_anon_id' /* domain: <value chosen in step 3, or omit for host-only> */ },
enableHttpInterceptor: true, // optional: adds X-Identity-Id to every HttpClient request
}),
],
})
export class AppModule {}
forRoot() must be called exactly once, in the root module only — a lazy
feature module should import bare IdentityModule (no forRoot()), which
registers nothing, so a second competing IdentityClient/anonymous id can't
get created by accident.
segmentProvider needs a caller-supplied analytics/analytics-node client
instance (client: analytics above) — this skill does not create that
instance; the target repo must already have (or add) its own Segment client
module and import it here.
Where identify()/reset() go (surface only — do not auto-edit)
import { Component, Inject } from '@angular/core'
import { IdentityService } from '@idhub/identity-adapter-angular'
@Component({ /* ... */ })
export class ExampleComponent {
constructor(@Inject(IdentityService) private readonly identity: IdentityService) {}
// identity.identify(userId, traits) belongs at the login handler found in step 4
// identity.reset() belongs at the logout handler found in step 4
}
SSR caveat: Angular Universal needs the companion Express middleware
APP_INITIALIZER only guarantees the anonymous id exists before the first
route renders in the browser — Angular has no request-time middleware
equivalent to Next.js's Edge middleware, so a server-rendered (Angular
Universal) app's first request has nothing to mint the cookie before that
first response goes out, without which the server render and the client
bootstrap that follows can each mint a different anonymous id. If the
target is Angular Universal, this is a required wiring step, not an edge
case to skip:
// server.ts (Angular Universal Express server) — write-if-absent
import { identityExpressMiddleware } from '@idhub/identity-adapter-angular/server'
server.use(identityExpressMiddleware({ cookie: { name: '_anon_id' } }))
// downstream: req.anonymousId is set, and Set-Cookie is appended (not
// replaced, so it composes with session/auth cookies set by other middleware)