Consent v0.2.0
Quickstart
Install the stylesheet and wire a complete controlled consent flow.
Install
npm install @peax/consent-banner-react@0.2.0 @peax/consent-banner-theme@0.2.0Import the stylesheet once in your application entry:
@import '@peax/consent-banner-theme/styles.css';Locales are included by the React package. Install @peax/consent-banner-locales@0.2.0 directly when your application imports its dictionaries or types.
Render and handle choices
This wrapper accepts saved choices through initialPreferences. Pass null for a new visitor. Its onCommit callback is where your application saves the choice and updates optional services.
'use client'
import { Banner } from '@peax/consent-banner-react'
import { useState } from 'react'
export type Preferences = Record<string, boolean>
type Props = {
initialPreferences: Preferences | null
onCommit: (preferences: Preferences) => void
}
export function CookieBanner({ initialPreferences, onCommit }: Props) {
const [open, setOpen] = useState(initialPreferences === null)
const [preferences, setPreferences] = useState<Preferences>(initialPreferences ?? {})
function commit(next: Preferences) {
onCommit(next) // The application saves this decision and enforces it.
setPreferences(next)
setOpen(false)
}
return (
<>
<button type="button" onClick={() => setOpen(true)}>
Cookie choices
</button>
<Banner
isOpen={open}
showFloatingButton={false}
hasAcceptRejectEqualWeight
cookiePolicyUrl="/cookies"
preferencesContent={Object.fromEntries(
Object.entries(preferences).map(([id, checked]) => [id, { checked }]),
)}
onMsg={msg => {
switch (msg.type) {
case 'on_accept_all':
commit({ essential: true, analytics: true, marketing: true })
break
case 'on_reject_all':
commit({ essential: true, analytics: false, marketing: false })
break
case 'on_apply_preferences':
commit(msg.preferences)
break
case 'on_change_preference':
case 'on_open_preferences':
case 'on_close_preferences':
break // Navigation and uncommitted drafts stay inside the banner.
}
}}
/>
</>
)
}
Connect your application
Restore saved preferences before mounting this wrapper, keeping server and client initial props consistent. Keep the wrapper mounted so the Cookie choices button can reopen it. This example disables the built-in floating button because it supplies that entry point; see preferences to use the floating button instead.
The Accept and Reject maps above match the three default categories. Adapt both maps when you change categories. Only Apply, Accept and Reject commit a decision; navigation and draft changes do not.
The example uses hasAcceptRejectEqualWeight so Accept and Reject have the same visual weight. Supply a real /cookies policy page in your application.
The wrapper expects a synchronous onCommit. If your persistence is asynchronous, build an explicit pending/error state and close only after the application accepts the decision. Do not silently dismiss a failed save.
Choose your framework
- Waku: client component and global CSS placement.
- Next.js App Router: client wrapper and root layout integration.
- Persistence and enforcement: storage lifecycle and revocation responsibilities.