@policystack/angular
Angular 18+ adapter — providePolicyStackConsent, ConsentService, *ocConsent
Angular 18+ adapter for Consent. Bridges @policystack/core/consent with Angular's signal reactivity.
Install#
pnpm add @policystack/core @policystack/angularPeer dependencies: @angular/core >= 18, @angular/common >= 18.
Setup#
Register the provider once at the root of your standalone application:
import { bootstrapApplication } from "@angular/platform-browser";
import { providePolicyStackConsent } from "@policystack/angular/consent";
import { localStorageAdapter } from "@policystack/core/consent/storage/local-storage";
import { AppComponent } from "./app.component";
bootstrapApplication(AppComponent, {
providers: [
providePolicyStackConsent({
config: {
categories: [
{ key: "essential", label: "Essential", locked: true },
{ key: "analytics", label: "Analytics" },
{ key: "marketing", label: "Marketing" },
],
adapter: localStorageAdapter(),
},
}),
],
});You can pass a pre-created store instead of config:
import { createConsentStore } from "@policystack/core/consent";
const store = createConsentStore({ categories });
providePolicyStackConsent({ store });API#
ConsentService#
Inject ConsentService anywhere to read consent state via signals and trigger actions.
import { Component, inject } from "@angular/core";
import { ConsentService } from "@policystack/angular/consent";
@Component({
selector: "app-banner",
standalone: true,
template: `
@if (consent.route() === "cookie") {
<div>
<button (click)="consent.acceptNecessary()">Necessary only</button>
<button (click)="consent.acceptAll()">Accept all</button>
<button (click)="consent.setRoute('preferences')">Customize</button>
</div>
}
`,
})
export class BannerComponent {
readonly consent = inject(ConsentService);
}Signal properties: route, categories, decisions, jurisdiction, policyVersion, decidedAt, repromptReason, state.
Methods: acceptAll, acceptNecessary, reject, toggle, save, setRoute, has, getConsentRecord, getPreviousRecord.
injectCategory(key)#
Granular per-category access. Must be called inside an injection context (e.g. a component constructor or field initializer).
import { Component } from "@angular/core";
import { injectCategory } from "@policystack/angular/consent";
@Component({
selector: "category-row",
standalone: true,
template: `
<label>
<input type="checkbox" [checked]="analytics.granted()" (change)="analytics.toggle()" />
Analytics
</label>
`,
})
export class CategoryRowComponent {
readonly analytics = injectCategory("analytics");
}*ocConsent directive#
Structural directive that conditionally renders content based on a consent expression. Mirrors @policystack/react/consent's <ConsentGate> and @policystack/vue/consent's <ConsentGate>.
import { Component } from "@angular/core";
import { ConsentGate } from "@policystack/angular/consent";
import { ChartComponent } from "./chart.component";
import { EnablePromptComponent } from "./enable-prompt.component";
@Component({
selector: "gated-chart",
standalone: true,
imports: [ConsentGate, ChartComponent, EnablePromptComponent],
template: `
<chart *ocConsent="'analytics'; else fallback"></chart>
<ng-template #fallback>
<enable-prompt></enable-prompt>
</ng-template>
<personalized-promo *ocConsent="{ and: ['analytics', 'marketing'] }"></personalized-promo>
`,
})
export class GatedChartComponent {}The directive emits no DOM wrapper — only the templated content (or its fallback) is rendered.
SSR (Angular Universal)#
providePolicyStackConsent runs the store factory once per request injector on the server, which is the right scope for cookie/header-based jurisdiction or storage. Use @policystack/core/consent/storage/server for a server-side adapter seeded from the inbound request, and the local-storage / cookie adapters in the browser. See @policystack/core/consent for storage adapter details.
Shared concepts#
Categories, GPC handling, jurisdiction resolvers, re-consent triggers, script gating (gateScript), and storage adapters all live in @policystack/core/consent — the Angular adapter is a thin reactivity wrapper. A working example is in examples/angular.
See also#
@policystack/core/consent— shared concepts and config reference@policystack/vite— build-time check for ungated cookie / vendor calls- Other adapters — React, Vue, Solid, Svelte
License#
Apache-2.0