@consentx/react
v1.0.1
Published
ConsentX cookie consent & CMP for React — GDPR, CCPA, DPDPA. Drop-in <ConsentXProvider> + useConsent() hook.
Downloads
241
Maintainers
Readme
@consentx/react
Cookie consent & CMP for React — GDPR, CCPA, DPDPA. Drop in a provider, paste your Site Key, and the ConsentX widget installs itself: banner, geo-aware config, Google Consent Mode v2, and pre-consent tracker blocking.
Model C (site-key). There is no server-side redirect handshake. You copy your Site Key from the ConsentX dashboard (Websites → your site) and pass it to
<ConsentXProvider>. Make sure your domain is on that site's allowlist in the dashboard (the dashboard "Add website" flow handles this).
Install
npm install @consentx/react
# or
pnpm add @consentx/react
# or
yarn add @consentx/reactreact >= 16.8 is a peer dependency (hooks).
Usage
Wrap your app once, near the root, with your Site Key:
import { ConsentXProvider } from '@consentx/react';
export default function App() {
return (
<ConsentXProvider siteKey="cx_live_xxxxxxxx">
<YourApp />
</ConsentXProvider>
);
}That is all that is required — the banner appears on load.
React the consent state with useConsent()
import { useConsent } from '@consentx/react';
function Analytics() {
const { granted, ready, hasConsent, open } = useConsent();
// Only boot analytics after the visitor grants the category.
if (ready && hasConsent('analytics')) {
// initAnalytics();
}
return (
<button onClick={open}>
Cookie settings ({granted.join(', ') || 'none granted yet'})
</button>
);
}useConsent() returns:
| Field | Type | Description |
| --- | --- | --- |
| granted | string[] | Granted category slugs from the latest cx:consent event (e.g. ['necessary','analytics']). |
| ready | boolean | true once at least one cx:consent event has fired. |
| hasConsent(category) | (s: string) => boolean | Convenience check for one category. |
| open() | () => void | Re-open the ConsentX preferences (calls window.ConsentX.open()). |
| siteKey / appUrl | string | The resolved configuration. |
Provider props
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| siteKey | string | — (required) | Your ConsentX Site Key (dashboard → Websites → your site). |
| appUrl | string | https://app.consentx.io | App host. Override for staging / self-hosted (e.g. https://consentx1.satyamrastogi.com). |
| consentMode | boolean | false | Emit Google Consent Mode v2 denied-by-default signals before analytics tags fire. The widget emits the update signals on the visitor's choice. |
Google Consent Mode v2
Set consentMode to seed denied-by-default signals before any analytics tag:
<ConsentXProvider siteKey="cx_live_xxxxxxxx" consentMode>
<YourApp />
</ConsentXProvider>Mount the provider above your analytics tags so the defaults push first.
How it works
<ConsentXProvider> injects exactly one module script into <head> after
mount (in a useEffect):
<script type="module" src="https://app.consentx.io/api/SITE_KEY/embed.js"></script>embed.js is self-contained: it injects the scoped widget CSS + JS, renders the
banner into a #consentx-cookie-consent div it appends to document.body,
reads geo/config from the server, exposes window.ConsentX, and emits the
cx:consent event (detail.granted = array of granted category slugs).
Injecting after mount (rather than in JSX) is deliberate: the widget appends its
mount node to <body> outside React's tree, so React reconciliation never
owns — and therefore never strips — #consentx-cookie-consent. The injection is
idempotent (keyed by src), so Fast Refresh / remounts never double-load it.
Next.js
Place the provider in your root layout / _app. It already defers injection to a
client effect, so the embed loads after hydration — no #consentx-cookie-consent
stripping. In the App Router, the provider is a Client Component (it uses hooks);
import it from a 'use client' boundary.
Build from source
npm install
npm run build # tsup → dist/ (ESM + CJS + .d.ts)
npm run typecheck # tsc --noEmitLicense
MIT © ConsentX
Cookie consent & CMP — GDPR, CCPA, DPDPA. Learn more at consentx.io.
