@consentstack/react
v0.2.1
Published
React hooks and components for ConsentStack consent management
Maintainers
Readme
@consentstack/react
React hooks and components for ConsentStack consent management.
Installation
npm install @consentstack/react
# or
pnpm add @consentstack/react
# or
yarn add @consentstack/reactPeer dependencies: react and react-dom ^18 or ^19.
Quick Start
Simple Usage (just the banner)
import { ConsentStack } from "@consentstack/react"
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<ConsentStack siteKey="pk_abc123" />
</body>
</html>
)
}With Hooks (conditional script loading)
import { ConsentStackProvider } from "@consentstack/react"
export default function RootLayout({ children }) {
return (
<ConsentStackProvider siteKey="pk_abc123">
{children}
</ConsentStackProvider>
)
}Hooks
useConsent()
Full consent state and control methods.
const {
consent, // Record<string, boolean> | null (effective consent)
config, // ConsentConfig | null
region, // string | null (e.g. "US-CA", "gdpr")
isLoading, // boolean
isReady, // boolean (consent state is known, no error)
hasDecision, // boolean (explicit decision exists)
error, // Error | null
setConsent, // (categories) => Promise<void>
hasConsent, // (category) => boolean
showBanner, // () => void
showPreferences, // () => void
hidePreferences, // () => void
isPreferencesOpen, // boolean
} = useConsent()Semantics worth knowing:
consentis effective consent: explicit decision, GPC, or implicit grant by consent model. It is not "null until the user decides". In an opt-out region it istruefor non-essential categories before the visitor touches the banner.isReadymeans consent state is known, not merely that the script loaded. Gating onisReady && hasConsent("analytics")is the recommended pattern; with the standard install, consent state is seeded from the edge and the gate passes immediately on the landing page.hasDecisionis whether an explicit choice exists (stored from a prior visit or made this session). Use it, notconsent === null, to decide whether to show a custom banner.
useConsentValue(category)
Optimized hook for a single category. Only re-renders when that category changes.
const hasAnalytics = useConsentValue("analytics") // booleanuseConsentEvent(event, callback)
Subscribe to SDK lifecycle events. Automatically cleans up on unmount.
useConsentEvent("preferences:open", () => {
analytics.track("consent_preferences_opened")
})Events: "ready", "consent", "error", "preferences:open", "preferences:close"
"ready"payload is{ config, consent, effectiveConsent, hasDecision }:consentis the stored explicit decision (ornull),effectiveConsentis the state the request blocker acts on."consent"fires on any effective-consent change, including init reconciliation."error"fires on SDK errors, including init aborts (site not configured, domain not registered).
Error Handling
const { error, isReady } = useConsent()
if (error) {
return <div>Consent SDK failed to load: {error.message}</div>
}The provider times out after 15 seconds by default. Customize with the timeout prop:
<ConsentStackProvider siteKey="pk_abc123" timeout={30000}>SSR Support
- Returns
isLoading: trueduring server-side rendering - Returns
falseforuseConsentValue()during SSR (safe default) - No hydration mismatches
License
MIT
