React Components
ConsentBanner
Render the banner inside ConsentProvider
Render ConsentBanner once inside ConsentProvider, next to ConsentDialog.
The quickstart mounts both in
src/consent.tsx:
The banner renders whatever the active policy rule requires. It reads the rule through the provider, so the same component serves every region:
- A
choiceprompt shows the actions the rule allows: reject and accept at equal prominence, plus customize when the rule offers it. - A
noticeprompt shows an "OK" button and a button styled as underlined text, labeled "Do not sell or share my data". The latter opens preferences. A notice never traps focus or locks scroll. - A rule with
prompt: 'none'renders nothing.
An opt-out rule with prompt: 'none' still has rights, so the preference
center and the dialog trigger stay available as the route to preferences. A
rule with model: 'none' owes no rights, so nothing renders unless you add
rights: ['preferences']. With no resolved rule at all, because resolution
failed, no rule matched and you set no default, or init is still withheld, no
consent surface renders: not the banner, the dialog, the widget, the
preferences link, or the trigger. They appear as soon as a rule resolves,
without a remount. offline() without policyRules resolves the recommended
pack, so it shows the strict opt-in banner until you pass a country.
Acknowledging a notice records its dismissal. It does not record consent or
change category permissions, including existing denials and privacy-signal
restrictions. Customize the label through common.acknowledge in your
translations, or use dismissButtonText for one banner.
The additional preferences button uses the opt-out label when appropriate. A choice prompt without Customize renders a "Manage preferences" button. Both are button elements that open the preference center; CSS gives them an underlined text appearance. They do not submit an opt-out by themselves.
preferenceControls recommends these extra buttons for the stock UI.
It does not verify disclosure or access to rights. Configure your legal links
and keep preferences reachable after the banner closes.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
title | ReactNode | translation | Overrides the title. Under a notice the default is cookieBanner.noticeTitle. |
description | ReactNode | translation | Overrides the description. Under a notice the default is cookieBanner.noticeDescription. |
acceptButtonText | ReactNode | common.acceptAll | Accept label. |
rejectButtonText | ReactNode | common.rejectAll | Reject label. |
customizeButtonText | ReactNode | common.customize | Customize label. |
dismissButtonText | ReactNode | common.acknowledge | Label of the notice acknowledgement. |
variant | PromptVariant | floating | Shape of the prompt. See Variants. |
position | PromptPosition | per variant | Where the prompt sits. Must be valid for the variant. |
blocking | boolean | true on wall | Backdrop, scroll lock, focus trap, and no outside dismissal, as one value. |
layout | ConsentBannerLayout | policy default | Orders and groups actions. Required actions the layout omits are restored. |
primaryButton | ConsentBannerButton | ConsentBannerButton[] | 'customize' | Which actions get the primary treatment. On a notice, dismiss is primary when it is the only action. |
direction | 'row' | 'column' | 'row' | How action groups flow. |
legalLinks | (keyof LegalLinks)[] | null | none | Which configured legal links render inline. |
hideBranding | boolean | false | Hides the "Secured by" tag. |
scrollLock | boolean | unset | Deprecated. Use blocking to control scrolling, focus and backdrop together. |
trapFocus | boolean | unset | Deprecated. Use blocking. |
disableAnimation | boolean | false | Skips enter and exit animations. |
noStyle | boolean | false | Removes the built-in styling from every part. |
Per-policy buttons
The default already makes Customize primary on a choice banner and OK primary on a notice. To set button order and treatment for specific rules, read the active policy inside the provider:
Render RegionalBanner inside ConsentProvider. The layout controls the
action groups; the opt-out preferences button still appears on a notice.
Required actions omitted from a layout are restored. Accept and Reject
keep equivalent default prominence.
Choose one brand color and make whichever action is primary use a filled button through the provider's theme:
Pass theme in ConsentProvider options. Per-action theme overrides such
as consentActions.dismiss take precedence over this primary style.
See customize for tokens and slots, and
policies for the rule IDs and coverage.
Variants
The policy decides which actions the banner offers. The variant decides the shape those actions take. Both come from the same component, so a bar for a notice region and a card for an opt-in region need no extra components.
Set the variant on the banner, or on the provider under
presentation.prompt when every banner should share it. The prop wins.
A floating card in a corner or centered on an edge. This is the default for every prompt. A notice keeps the same card, with its right link and "OK" in the footer.
A bar across the full width of the viewport. From 1024px wide the text, the right links, and the controls share one row. Opt in to it for regions that expect a classic cookie bar.
A compact card with smaller type. The full description and its legal links remain visible. Pair it with a short notice.
A centered card over a backdrop that blocks the page until the visitor answers. A wall is always blocking.
Each variant accepts its own positions:
| Variant | Positions | Default |
|---|---|---|
floating | bottom-left, bottom-right, top-left, top-right, bottom-center, top-center | bottom-left |
bar | top, bottom | bottom |
widget | bottom-left, bottom-right, top-left, top-right | bottom-right |
wall | center | center |
A default corner mirrors left and right for right-to-left languages. A
position you set is never mirrored. A position that is not valid for the
variant falls back to the default and logs an invalid-position diagnostic
in development.
blocking controls the backdrop, scroll lock, and focus trap together.
An explicit value overrides the deprecated scrollLock and trapFocus
options. Without blocking, either legacy option set to false selects
non-blocking behavior; otherwise a legacy true selects blocking behavior.
A choice wall always blocks. Notices always stay non-blocking, and asking
for a notice wall falls back to floating with an invalid-variant
diagnostic. Blocking banners carry role="dialog" and aria-modal="true".
Non-blocking banners leave page controls usable by keyboard and pointer.
PromptVariant and PromptPosition are exported from c15t/react.
Compound parts can read the resolved shape with useConsentBannerSurface(),
which returns variant, position, positionSource (host or default),
and blocking.
Composition
Every part is available as ConsentBanner.<Part> for custom layouts. The
parts read the same policy state the pre-built banner does, so a custom layout
still gets the right actions for the active rule.
ConsentBanner.PolicyActions renders the resolved action groups and, before
them, the additional preferences buttons. Pass children to replace those
buttons while retaining the policy action groups. This supports custom labels
and button markup.
Use the individual parts when you need a different order or your own markup:
ConsentBanner.AcceptButton,ConsentBanner.RejectButton,ConsentBanner.CustomizeButton, andConsentBanner.DismissButtonrender one action each.DismissButtondefaults its label tocommon.acknowledge.ConsentBanner.Rightsrenders the additional preferences buttons. It renders nothing when the list is empty. Passrightsto override the list.ConsentBanner.RightLinkrenders a single right.rightis'opt-out'or'preferences'. By default it is a button element styled as an underlined text link, carryingdata-action="right"anddata-right; it opens the preference center on click and acceptsasChildto render your own element, such as an anchor to a dedicated opt-out page.
useBannerCopy() returns the title, description, and prompt kind the banner
would use, for custom headers that still follow the notice copy.
Data attributes
The root element carries attributes you can target from CSS or Tailwind. The
card carries data-state (open or closed) for the enter and exit
animations.
| Attribute | Values |
|---|---|
data-prompt | choice, notice |
data-model | opt-in, opt-out, iab |
data-variant | floating, bar, widget, wall |
data-position | The resolved position for the variant |
data-blocking | true, present only while blocking |
Each action button carries data-action, and each right link carries
data-action="right" plus data-right. The built-in stylesheet keys every
variant's geometry on data-variant and data-position, and uses
data-prompt="notice" to lay the footer out as one row with the right
links leading and "OK" trailing.