HTML Components
Banner
What the banner shows
The banner is the first prompt a visitor sees. c15t.js renders it when the
resolved policy asks for a choice or a notice and the visitor has not answered
it yet. A returning visitor with a valid choice, and a visitor whose policy
needs no prompt, sees no banner.
The banner has a title, a description, optional legal links, a row of buttons and a "Secured by" tag. You do not add markup for it. The quickstart tag is enough:
Which buttons it shows
The policy decides the buttons, not the page:
| Policy prompt | Buttons |
|---|---|
| A choice | The actions the policy allows. By default that is Reject All and Accept All at equal size, then Customize. |
| A choice under a policy with an opt-out right and no reject action | The allowed actions plus "Do not sell or share my data", which opens the dialog. |
| A notice | "OK", which acknowledges the notice, plus any other action the policy allows. |
Accept and reject record a choice and close the banner in the same click. Customize opens the preference dialog and records nothing. The notice button records that the visitor saw the notice. It grants nothing. How consent works explains the difference.
presentation.prompt can reorder buttons, group them or make one primary.
When your layout drops a button the policy requires, c15t puts it back, and it
keeps accept and reject equally prominent where the policy says so.
Change the text
Queue a config call before the tag and set the banner options under
ui.banner:
These options replace the text in every language. For copy that changes with the visitor's language, use translations.
Banner options
These go under ui.banner.
| Option | Type | Default | What it does |
|---|---|---|---|
title | string | translated title | Heading. A notice uses the notice title by default. |
description | string | translated description | Body text. A notice uses the notice description by default. |
acceptButtonText | string | "Accept All" | Label of the accept button. |
rejectButtonText | string | "Reject All" | Label of the reject button. |
customizeButtonText | string | "Customize" | Label of the button that opens the dialog. |
legalLinks | list of privacyPolicy, cookiePolicy, termsOfService, or null | none | Which configured legal links to show after the description. null or [] shows none. |
hideBranding | boolean | false | Hide the "Secured by" tag. The IAB banner always keeps it. |
scrollLock | boolean | from presentation | Deprecated. Use presentation.prompt.blocking. |
trapFocus | boolean | from presentation | Deprecated. Use presentation.prompt.blocking. |
The dismiss button of a notice always uses the translated
common.acknowledge label. Change it through i18n.
Change the layout
presentation.prompt picks the banner's shape, position and button layout:
variant | Positions |
|---|---|
floating (default) | bottom-left (default), bottom-right, top-left, top-right, bottom-center, top-center |
bar | bottom (default), top |
widget | bottom-right (default), bottom-left, top-left, top-right |
wall | center |
presentation.prompt option | What it does |
|---|---|
layout | The order of the buttons. A nested array groups buttons together. |
primaryActions | The buttons drawn with the primary style. |
direction | row (default) or column. |
uiProfile | compact (default) sizes buttons to their labels. balanced and strict stretch every button and stack the groups. |
blocking | Dim the page, stop it scrolling and keep focus in the banner. |
A notice never blocks the page and cannot use wall. A wall always blocks.
An invalid position falls back to the variant's default. In a right-to-left
language, a default left or right position flips.
Show legal links
Add the link URLs to the tag. The banner and the dialog both show them:
To show different links on each surface, set legalLinks in config and list
the keys in ui.banner.legalLinks and ui.dialog.legalLinks. Each link opens
in a new tab unless its target says otherwise.
Keyboard and screen readers
- A non-blocking banner is a
role="region"landmark named by its title. Focus stays where it was, and the page remains usable. - A blocking banner is a modal
role="dialog". c15t moves focus into it, keeps Tab inside it and stops the page scrolling until the visitor answers. - The banner sets
langanddirfrom the resolved language, so screen readers use the right voice and right-to-left text lays out correctly. - Every action is a native
button. The banner has no close button, because closing it without answering would not settle the prompt. - Enter and exit transitions follow the visitor's reduced motion setting. Set
ui.disableAnimationto turn them off for everyone.
Style it
Theme tokens change colors, radius, fonts and spacing for the banner and every
other surface. See customize. To target one
part, use its data-testid in ui.css:
data-testid | Element |
|---|---|
consent-banner-root | The positioned wrapper. Carries data-variant, data-position and data-blocking. |
consent-banner-card | The card or bar. |
consent-banner-title, consent-banner-description | The heading and body text. |
consent-banner-legal-link-privacyPolicy and the other link keys | Each legal link. |
consent-banner-footer | The button row. |
consent-banner-accept-button, consent-banner-reject-button, consent-banner-customize-button, consent-banner-dismiss-button | Each action button. |
consent-banner-branding | The "Secured by" tag. |
consent-banner-overlay | The backdrop of a blocking banner. |
Turn the banner off
ui: { banner: false } renders no banner. The policy still requires a prompt,
so render your own with headless instead of
leaving visitors without one.
Check it works
Open the page in a private window.
- The banner appears once the policy resolves, with the buttons your policy requires.
- Press Tab. Focus reaches every button in order.
- Click Reject All and reload. The banner stays closed.
- In the DevTools panel's Location tab, pick a country with a different policy and run init. The banner changes to that policy's buttons, or disappears.