Cookie Consent

Pro

A GDPR-ready consent surface in two coordinated pieces over one shared state: a non-blocking banner and a preferences dialog with a toggle per cookie category. The parts are the real DS components.

We value your privacy

We use cookies to enhance your experience and analyse traffic. Read our Cookie Policy.

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Activate your Pro license (once per machine)npx koalaui-cli@latest login <key># Add this component (its dependencies come along)npx koalaui-cli@latest add cookie-consent

Usage#

This example is part of Koala UI Pro

The preview is yours to explore. Its code comes with a Pro license, paid once and used in every project.

Have a license? Unlock it here

Anatomy#

import {  CookieConsent,  CookieBanner,  CookieBannerIcon,  CookieBannerContent,  CookieBannerTitle,  CookieBannerDescription,  CookieBannerDetails,  CookieDetailList,  CookieBannerActions,  CookieBannerDetailsTrigger,  CookieCustomizeButton,  CookieRejectAllButton,  CookieAcceptAllButton,  CookiePreferences,  CookiePreferencesTrigger,  CookiePreferencesContent,  CookiePreferencesHeader,  CookiePreferencesTitle,  CookiePreferencesDescription,  CookieCategoryList,  CookiePreferencesFooter,  CookieSavePreferencesButton,} from "@/components/ui/cookie-consent"<CookieConsent>  <CookieBanner>    <CookieBannerIcon />    <CookieBannerContent>      <CookieBannerTitle />      <CookieBannerDescription />    </CookieBannerContent>    <CookieBannerDetails>      <CookieDetailList />    </CookieBannerDetails>    <CookieBannerActions>      <CookieBannerDetailsTrigger />      <CookieCustomizeButton />      <CookieRejectAllButton />      <CookieAcceptAllButton />    </CookieBannerActions>  </CookieBanner>  <CookiePreferences>    <CookiePreferencesTrigger />    <CookiePreferencesContent>      <CookiePreferencesHeader>        <CookiePreferencesTitle />        <CookiePreferencesDescription />      </CookiePreferencesHeader>      <CookieCategoryList />      <CookiePreferencesFooter>        <CookieSavePreferencesButton />      </CookiePreferencesFooter>    </CookiePreferencesContent>  </CookiePreferences></CookieConsent>

Details on hover#

CookieBannerDetails keeps the banner clean: it stays folded away and unrolls above the copy on hover or keyboard focus, so the buttons never move under the pointer. CookieDetailList fills it from your categories, listing the cookies of each one with its purpose, provider and duration. Touch screens have no hover, so CookieBannerDetailsTrigger shows there, and only there. Escape folds it again.

We value your privacy

We use cookies to run the site and, if you agree, to measure it and show relevant ads.

Essential cookies only#

A site that stores only what it needs to work (a sign-in, a saved theme) needs no consent, so there is nothing to accept or reject, only something to know. layout="launcher" rests the banner as its icon alone in a small circle. On hover, focus or a tap, the circle grows into the card and the icon slides to its seat beside the title, with the reason and the full list above. This is the notice koalaui.com runs.

Only essential cookies

No analytics, no ads, no tracking.

Remember the choice#

Pass storageKey and the root keeps the answer in localStorage: the banner shows only until the visitor answers, the preferences come back on the next visit, and every open tab follows. The record is dated and versioned. Bump version when your categories change and everyone is asked again; after maxAgeDays (six months by default) the choice expires and the banner returns. Nothing optional is on until the visitor says so, so gate each script on the preferences map.

This example is part of Koala UI Pro

The preview is yours to explore. Its code comes with a Pro license, paid once and used in every project.

Have a license? Unlock it here

Preferences dialog#

The configurator is a DS Dialog bound to the same shared state. CookieCategoryList maps your categories into rows, each with a leading icon, a description, and a Switch. Required categories render locked-on with an Always on badge. Open it from the banner's CookieCustomizeButton, or from a standalone CookiePreferencesTrigger anywhere on the page.

Position#

position anchors the banner: bottom is a full-bleed bar that rows its content out on wide screens, while bottom-left and bottom-right are compact floating cards. Each slides in from its own edge. layout arranges the parts inside: stack (the default) is a column, inline one slim row, and launcher (corners only) the icon alone until the banner is expanded.

Cookies on this site

A full-width bar lays its copy and actions out in a row on wide screens.

We value your privacy

A compact corner card that stacks its content and stretches its actions.

API reference#

CookieConsent

The root and single source of truth: owns the category booleans, the dialog's open state and the three actions; renders no DOM. Every part that renders an element accepts className, merged last.

PropTypeDefaultDescription
categories*CookieCategoryDef[]-The categories to manage, in display order: { id, label, description?, required?, icon?, cookies? }.
valueRecord<string, boolean>-Controlled preferences map, { [id]: boolean }. Required categories are always clamped on.
defaultValueRecord<string, boolean>-Initial preferences when uncontrolled; a stored answer wins over it. Anything unset is off.
onValueChange(value: Record<string, boolean>) => void-Called whenever a toggle or action changes the map.
onAcceptAll(value: Record<string, boolean>) => void-Called when the visitor accepts every category.
onRejectAll(value: Record<string, boolean>) => void-Called when the visitor rejects all but the required categories.
onSave(value: Record<string, boolean>) => void-Called when the visitor saves the current selection.
openboolean-Controlled open state of the preferences dialog.
defaultOpenbooleanfalseInitial dialog open state when uncontrolled.
onOpenChange(open: boolean) => void-Called when the dialog opens or closes.
defaultConsentedbooleanfalseStart with the banner hidden, for a visitor whose answer you stored yourself.
storageKeystring-Remember the answer in localStorage under this key, dated and versioned, and keep every tab in step. Omit to persist it yourself.
versionnumber | string1Your cookie policy's version; an answer stored under another one no longer counts, so the banner asks again.
maxAgeDaysnumber180Days a stored answer stays valid before the banner asks again. Needs storageKey.
density"comfortable" | "compact""compact"Banner padding (20 or 16px) and category rows; the dialog follows it too. Falls back to the nearest DensityProvider.

useCookieConsent

Reads the root's state from a custom surface: prefs, categories, setPreference(id, value), acceptAll(), rejectAll(), save(), dialogOpen, setDialogOpen(open) and bannerVisible. Call it inside CookieConsent.

CookieBanner

The non-blocking consent card, a fixed <div role="region"> that animates in, and out once a choice is made; forwards all native <div> props. Declares --surface, so nested controls blend with it.

PropTypeDefaultDescription
position"bottom" | "bottom-left" | "bottom-right""bottom-right"bottom is a full-bleed bar that rows out from lg; the corners are floating cards.
layout"stack" | "inline" | "launcher""stack"A column, one slim row, or (corners only, needs CookieBannerIcon) the icon alone in a circle that grows into the inline card on hover, focus or tap.
Data attributeDescription
data-state"open" while visible, "closed" during the exit animation.
data-expandedPresent while the details layer (or a launcher) is open.
CSS variableDescription
--surfaceSet to var(--popover), read by nested controls.

CookieBannerIcon

An optional leading glyph: pass a Koala icon, sized to 20px. Forwards all native <div> props.

CookieBannerContent

The title and description column. Forwards all native <div> props.

CookieBannerTitle

The banner's heading. Forwards all native <p> props.

CookieBannerDescription

Muted supporting copy, usually with a link to your policy. Forwards all native <p> props.

CookieBannerDetails

A layer folded away at rest that unrolls upward from the top of the banner on hover, keyboard focus or CookieBannerDetailsTrigger; Escape folds it. Forwards all native <div> props.

Data attributeDescription
data-state"open" or "closed".

CookieBannerDetailsTrigger

Opens and closes the details layer on touch screens, hidden where a pointer can hover. Without children it is an icon-only caret that turns as the layer opens; forwards every Button prop.

PropTypeDefaultDescription
variantButtonProps["variant"]"ghost"Any Button variant.

CookieBannerActions

The action cluster; stacked corner cards stretch its buttons into an even row. Forwards all native <div> props.

CookieDetailList

Every category with the cookies it sets (name, duration, purpose, provider), read from the root's categories; a category without cookies shows its description. Forwards all native <div> props.

CSS variableDescription
--cookie-rowEach line's place in the stagger inside CookieBannerDetails, set per line.

CookiePreferences

The preferences dialog root, a Koala Dialog bound to the root's open state; renders no DOM. Forwards all Dialog props.

CookiePreferencesTrigger

Opens the dialog from your own element, Koala's DialogTrigger. Renders a <button> and forwards all its props.

PropTypeDefaultDescription
asChildbooleanfalseMerge onto your own element, such as a footer link.

CookiePreferencesContent

The dialog panel, Koala's DialogContent with the root's density; forwards all its props.

PropTypeDefaultDescription
size"sm" | "md" | "lg" | "xl""md"Dialog width; md is 480px.

CookiePreferencesHeader

Koala's DialogHeader, re-exported so the dialog reads from one import.

CookiePreferencesTitle

Koala's DialogTitle, which names the dialog for assistive tech.

CookiePreferencesDescription

Koala's DialogDescription.

CookiePreferencesFooter

Koala's DialogFooter, the row for the save and reject buttons.

CookieCategoryList

Maps the root's categories into CookieCategory rows inside one bordered container with dividers, a role="group". Takes className only.

CookieCategory

One row: icon, a <label> for the Switch, description and the Switch. A required category shows an Always on badge and a disabled, checked Switch.

PropTypeDefaultDescription
category*CookieCategoryDef-The category to render; its id keys into the preferences map.

CookieAcceptAllButton

A Koala Button with accept-all bound; forwards every Button prop, and your onClick runs after the action.

PropTypeDefaultDescription
variantButtonProps["variant"]"primary"Any Button variant.
childrenReact.ReactNode"Accept all"The label.

CookieRejectAllButton

A Koala Button with reject-all bound; forwards every Button prop, and your onClick runs after the action.

PropTypeDefaultDescription
variantButtonProps["variant"]"secondary"Any Button variant.
childrenReact.ReactNode"Reject all"The label.

CookieCustomizeButton

A Koala Button with opening the preferences dialog bound; forwards every Button prop, and your onClick runs after the action.

PropTypeDefaultDescription
variantButtonProps["variant"]"ghost"Any Button variant.
childrenReact.ReactNode"Customize"The label.

CookieSavePreferencesButton

A Koala Button with saving the current selection bound; forwards every Button prop, and your onClick runs after the action.

PropTypeDefaultDescription
variantButtonProps["variant"]"primary"Any Button variant.
childrenReact.ReactNode"Save preferences"The label.

FAQ#

Use Cookie Consent when you need a GDPR/ePrivacy consent flow specifically: it pairs a non-blocking CookieBanner with a CookiePreferences dialog over one shared state, so toggling a category and clicking Accept all mutate the same source of truth. A plain Dialog gives you a modal but none of the category booleans, the always-on clamping, or the coordinated accept/reject/save actions.