@consentx/angular 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/README.md ADDED
@@ -0,0 +1,221 @@
1
+ <p align="left">
2
+ <img src="./assets/consentx-logo.svg" alt="ConsentX" height="56" />
3
+ </p>
4
+
5
+ # @consentx/angular
6
+
7
+ **Cookie consent & CMP for Angular — GDPR, CCPA, DPDPA.**
8
+
9
+ Drop ConsentX into any Angular app. The package injects the ConsentX embed into
10
+ `<head>` on app init and gives you a service to read the visitor's consent state
11
+ reactively. No backend, no redirect handshake — you supply your **Site Key** and
12
+ the banner installs itself.
13
+
14
+ - Renders the ConsentX banner (the widget appends `#consentx-cookie-consent` to
15
+ `document.body` and reads geo/config from the server).
16
+ - Exposes consent decisions via the `cx:consent` event as Angular observables.
17
+ - Optional Google Consent Mode v2 denied-by-default defaults.
18
+ - SSR-safe (Angular Universal): no-op on the server, injects after browser boot.
19
+ - Works with both NgModule and standalone (`bootstrapApplication`) apps.
20
+
21
+ ---
22
+
23
+ ## How connect works (site-key model)
24
+
25
+ ConsentX for Angular uses the **site-key model** (Model C in the ConsentX
26
+ Connect spec). There is no server-side OAuth-style redirect:
27
+
28
+ 1. In the [ConsentX dashboard](https://app.consentx.io) go to **Websites → your
29
+ site** and **copy the Site Key**.
30
+ 2. Make sure your site's domain is on that website's **allowlist** (the
31
+ dashboard "Add website" flow handles this).
32
+ 3. Pass the Site Key to `ConsentXModule.forRoot()` / `provideConsentX()`.
33
+
34
+ That's it — the embed (`https://app.consentx.io/api/SITE_KEY/embed.js`) loads on
35
+ app init and the banner appears.
36
+
37
+ ---
38
+
39
+ ## Install
40
+
41
+ ```bash
42
+ npm install @consentx/angular
43
+ # or
44
+ yarn add @consentx/angular
45
+ # or
46
+ pnpm add @consentx/angular
47
+ ```
48
+
49
+ **Peer dependencies:** `@angular/core`, `@angular/common` (>= 15), `rxjs` (>= 7).
50
+
51
+ ---
52
+
53
+ ## Usage
54
+
55
+ ### Standalone apps (`bootstrapApplication`)
56
+
57
+ ```ts
58
+ // main.ts
59
+ import { bootstrapApplication } from '@angular/platform-browser';
60
+ import { provideConsentX } from '@consentx/angular';
61
+ import { AppComponent } from './app/app.component';
62
+
63
+ bootstrapApplication(AppComponent, {
64
+ providers: [
65
+ provideConsentX({ siteKey: 'YOUR_SITE_KEY' }),
66
+ ],
67
+ });
68
+ ```
69
+
70
+ ### NgModule apps
71
+
72
+ ```ts
73
+ // app.module.ts
74
+ import { NgModule } from '@angular/core';
75
+ import { BrowserModule } from '@angular/platform-browser';
76
+ import { ConsentXModule } from '@consentx/angular';
77
+ import { AppComponent } from './app.component';
78
+
79
+ @NgModule({
80
+ imports: [
81
+ BrowserModule,
82
+ ConsentXModule.forRoot({ siteKey: 'YOUR_SITE_KEY' }),
83
+ ],
84
+ declarations: [AppComponent],
85
+ bootstrap: [AppComponent],
86
+ })
87
+ export class AppModule {}
88
+ ```
89
+
90
+ The embed is injected automatically on app init. There is no component to add to
91
+ your template — the ConsentX widget mounts itself into `#consentx-cookie-consent`
92
+ on `document.body`.
93
+
94
+ ---
95
+
96
+ ## Reading consent state
97
+
98
+ Inject `ConsentXService` anywhere and react to the visitor's choice:
99
+
100
+ ```ts
101
+ import { Component } from '@angular/core';
102
+ import { AsyncPipe, NgIf } from '@angular/common';
103
+ import { ConsentXService } from '@consentx/angular';
104
+
105
+ @Component({
106
+ selector: 'app-analytics',
107
+ standalone: true,
108
+ imports: [AsyncPipe, NgIf],
109
+ template: `
110
+ <div *ngIf="analyticsAllowed$ | async">
111
+ <!-- analytics-dependent UI -->
112
+ </div>
113
+ <button (click)="consentx.openPreferences()">Cookie settings</button>
114
+ `,
115
+ })
116
+ export class AnalyticsComponent {
117
+ // Stream of granted category slugs, e.g. ['analytics', 'marketing'].
118
+ readonly granted$ = this.consentx.granted$;
119
+
120
+ readonly analyticsAllowed$ = this.consentx.state$;
121
+
122
+ constructor(public consentx: ConsentXService) {
123
+ this.consentx.granted$.subscribe((granted) => {
124
+ if (granted.includes('analytics')) {
125
+ // load your analytics SDK here
126
+ }
127
+ });
128
+ }
129
+ }
130
+ ```
131
+
132
+ Synchronous accessors are available too:
133
+
134
+ ```ts
135
+ this.consentx.hasConsent('analytics'); // boolean
136
+ this.consentx.getGranted(); // string[]
137
+ this.consentx.getState(); // { loaded, decided, granted, detail }
138
+ ```
139
+
140
+ ---
141
+
142
+ ## Configuration
143
+
144
+ `provideConsentX(config)` and `ConsentXModule.forRoot(config)` accept:
145
+
146
+ | Option | Type | Default | Description |
147
+ | ------------- | --------- | --------------------------- | -------------------------------------------------------------------------------------------- |
148
+ | `siteKey` | `string` | — (required) | Your ConsentX Site Key (dashboard → Websites → your site). |
149
+ | `appUrl` | `string` | `https://app.consentx.io` | Override the ConsentX app host (e.g. staging). |
150
+ | `consentMode` | `boolean` | `false` | Print the Google Consent Mode v2 denied-by-default stub before any analytics tag fires. |
151
+ | `manualLoad` | `boolean` | `false` | Skip auto-injection on init; call `consentx.load()` yourself at a custom point. |
152
+
153
+ ### Google Consent Mode v2
154
+
155
+ ```ts
156
+ provideConsentX({ siteKey: 'YOUR_SITE_KEY', consentMode: true });
157
+ ```
158
+
159
+ The denied-by-default defaults are pushed to `dataLayer` before the embed loads.
160
+ The ConsentX widget then emits the `gtag('consent','update',…)` calls on the
161
+ visitor's choice.
162
+
163
+ ### Staging / self-hosted host
164
+
165
+ ```ts
166
+ provideConsentX({
167
+ siteKey: 'YOUR_SITE_KEY',
168
+ appUrl: 'https://consentx1.satyamrastogi.com',
169
+ });
170
+ ```
171
+
172
+ ### Manual / deferred load
173
+
174
+ ```ts
175
+ provideConsentX({ siteKey: 'YOUR_SITE_KEY', manualLoad: true });
176
+ // ...later, e.g. inside a route guard or after consent UX is mounted:
177
+ this.consentx.load();
178
+ ```
179
+
180
+ ---
181
+
182
+ ## Service API
183
+
184
+ | Member | Returns | Description |
185
+ | ---------------------------- | ---------------------- | ------------------------------------------------------------------ |
186
+ | `state$` | `Observable<State>` | Full consent state stream. |
187
+ | `granted$` | `Observable<string[]>` | Granted category slugs (distinct). |
188
+ | `getState()` | `ConsentXState` | Synchronous full snapshot. |
189
+ | `getGranted()` | `string[]` | Synchronous granted slugs. |
190
+ | `hasConsent(slug)` | `boolean` | Whether a given category is granted. |
191
+ | `load()` | `void` | Inject the embed (idempotent). |
192
+ | `openPreferences()` | `boolean` | Re-open the ConsentX preferences dialog (`window.ConsentX.open`). |
193
+
194
+ `ConsentXState` is `{ loaded, decided, granted, detail }`.
195
+
196
+ ---
197
+
198
+ ## SSR (Angular Universal)
199
+
200
+ The service guards every DOM call behind `isPlatformBrowser`, so on the server
201
+ it is a no-op. The embed is injected via `APP_INITIALIZER`, which runs after the
202
+ app boots in the browser — the SPA-safe load point that prevents Angular's DOM
203
+ reconciliation from stripping the appended `#consentx-cookie-consent` div.
204
+
205
+ ---
206
+
207
+ ## Build
208
+
209
+ ```bash
210
+ npm install
211
+ npm run build # ng-packagr → ./dist
212
+ ```
213
+
214
+ The build produces an Angular Package Format (APF) distributable in `dist/`,
215
+ publishable to npm.
216
+
217
+ ---
218
+
219
+ ## License
220
+
221
+ MIT © [ConsentX](https://consentx.io)