@consentx/angular
v1.0.1
Published
ConsentX cookie consent & CMP for Angular — GDPR, CCPA, DPDPA. Inject the ConsentX embed and read consent state from a service. Site-key model, no server handshake.
Maintainers
Readme
@consentx/angular
Cookie consent & CMP for Angular — GDPR, CCPA, DPDPA.
Drop ConsentX into any Angular app. The package injects the ConsentX embed into
<head> on app init and gives you a service to read the visitor's consent state
reactively. No backend, no redirect handshake — you supply your Site Key and
the banner installs itself.
- Renders the ConsentX banner (the widget appends
#consentx-cookie-consenttodocument.bodyand reads geo/config from the server). - Exposes consent decisions via the
cx:consentevent as Angular observables. - Optional Google Consent Mode v2 denied-by-default defaults.
- SSR-safe (Angular Universal): no-op on the server, injects after browser boot.
- Works with both NgModule and standalone (
bootstrapApplication) apps.
How connect works (site-key model)
ConsentX for Angular uses the site-key model (Model C in the ConsentX Connect spec). There is no server-side OAuth-style redirect:
- In the ConsentX dashboard go to Websites → your site and copy the Site Key.
- Make sure your site's domain is on that website's allowlist (the dashboard "Add website" flow handles this).
- Pass the Site Key to
ConsentXModule.forRoot()/provideConsentX().
That's it — the embed (https://app.consentx.io/api/SITE_KEY/embed.js) loads on
app init and the banner appears.
Install
npm install @consentx/angular
# or
yarn add @consentx/angular
# or
pnpm add @consentx/angularPeer dependencies: @angular/core, @angular/common (>= 15), rxjs (>= 7).
Usage
Standalone apps (bootstrapApplication)
// main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { provideConsentX } from '@consentx/angular';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, {
providers: [
provideConsentX({ siteKey: 'YOUR_SITE_KEY' }),
],
});NgModule apps
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ConsentXModule } from '@consentx/angular';
import { AppComponent } from './app.component';
@NgModule({
imports: [
BrowserModule,
ConsentXModule.forRoot({ siteKey: 'YOUR_SITE_KEY' }),
],
declarations: [AppComponent],
bootstrap: [AppComponent],
})
export class AppModule {}The embed is injected automatically on app init. There is no component to add to
your template — the ConsentX widget mounts itself into #consentx-cookie-consent
on document.body.
Reading consent state
Inject ConsentXService anywhere and react to the visitor's choice:
import { Component } from '@angular/core';
import { AsyncPipe, NgIf } from '@angular/common';
import { ConsentXService } from '@consentx/angular';
@Component({
selector: 'app-analytics',
standalone: true,
imports: [AsyncPipe, NgIf],
template: `
<div *ngIf="analyticsAllowed$ | async">
<!-- analytics-dependent UI -->
</div>
<button (click)="consentx.openPreferences()">Cookie settings</button>
`,
})
export class AnalyticsComponent {
// Stream of granted category slugs, e.g. ['analytics', 'marketing'].
readonly granted$ = this.consentx.granted$;
readonly analyticsAllowed$ = this.consentx.state$;
constructor(public consentx: ConsentXService) {
this.consentx.granted$.subscribe((granted) => {
if (granted.includes('analytics')) {
// load your analytics SDK here
}
});
}
}Synchronous accessors are available too:
this.consentx.hasConsent('analytics'); // boolean
this.consentx.getGranted(); // string[]
this.consentx.getState(); // { loaded, decided, granted, detail }Configuration
provideConsentX(config) and ConsentXModule.forRoot(config) accept:
| Option | Type | Default | Description |
| ------------- | --------- | --------------------------- | -------------------------------------------------------------------------------------------- |
| siteKey | string | — (required) | Your ConsentX Site Key (dashboard → Websites → your site). |
| appUrl | string | https://app.consentx.io | Override the ConsentX app host (e.g. staging). |
| consentMode | boolean | false | Print the Google Consent Mode v2 denied-by-default stub before any analytics tag fires. |
| manualLoad | boolean | false | Skip auto-injection on init; call consentx.load() yourself at a custom point. |
Google Consent Mode v2
provideConsentX({ siteKey: 'YOUR_SITE_KEY', consentMode: true });The denied-by-default defaults are pushed to dataLayer before the embed loads.
The ConsentX widget then emits the gtag('consent','update',…) calls on the
visitor's choice.
Staging / self-hosted host
provideConsentX({
siteKey: 'YOUR_SITE_KEY',
appUrl: 'https://consentx1.satyamrastogi.com',
});Manual / deferred load
provideConsentX({ siteKey: 'YOUR_SITE_KEY', manualLoad: true });
// ...later, e.g. inside a route guard or after consent UX is mounted:
this.consentx.load();Service API
| Member | Returns | Description |
| ---------------------------- | ---------------------- | ------------------------------------------------------------------ |
| state$ | Observable<State> | Full consent state stream. |
| granted$ | Observable<string[]> | Granted category slugs (distinct). |
| getState() | ConsentXState | Synchronous full snapshot. |
| getGranted() | string[] | Synchronous granted slugs. |
| hasConsent(slug) | boolean | Whether a given category is granted. |
| load() | void | Inject the embed (idempotent). |
| openPreferences() | boolean | Re-open the ConsentX preferences dialog (window.ConsentX.open). |
ConsentXState is { loaded, decided, granted, detail }.
SSR (Angular Universal)
The service guards every DOM call behind isPlatformBrowser, so on the server
it is a no-op. The embed is injected via APP_INITIALIZER, which runs after the
app boots in the browser — the SPA-safe load point that prevents Angular's DOM
reconciliation from stripping the appended #consentx-cookie-consent div.
Build
npm install
npm run build # ng-packagr → ./distThe build produces an Angular Package Format (APF) distributable in dist/,
publishable to npm.
License
MIT © ConsentX
