1ConsentConsentDocs
Custom consent designs

Data bindings and localization

The host provides data when mounting a view. Template files cannot execute custom requests; use configured content, services, appearance, and framework settings.

Runtime roots

RootContent
uiCurrent localized content and ui.view: titles, descriptions, buttons, legal links, template labels
categoriesCategories with localized names/descriptions and nested services; empty categories omitted
servicesAll configured services with localized display fields
uncategorizedServicesServices outside rendered categories; preserve these in custom preferences
configRuntime configuration and framework-specific settings
consent.categories, consent.servicesConsent maps at mount; use controlled bindings for inputs
appearancePresentation settings and flags such as showClose, showCategoriesInNotice, useSwitchCategories
frameworkActive framework configuration
languagescurrent, supported languages, showSelector, and options with code/label
tcfConditional TCF display collections, including purposes and vendors, when GVL data exists
usConditional US opt-out and GPC state from the active engine

These roots do not permit arbitrary invented properties. Inspect the supplied view for the selected framework. GDPR cannot assume TCF/US roots exist. Colon paths such as config:framework.type address a named base; dot paths are clearer for most designs.

Localized content

<h2>{{ ui.title }}</h2>
<p>{{ ui.description }}</p>
<button type="button" data-1c="command:acceptAll">{{ ui.button.acceptAll }}</button>

Preferences use paths such as ui.details.title, ui.details.description, and ui.details.button.save. The current notice title is ui.title, not the older ui.notice.title.

Configure every enabled locale in the Dashboard. Reusing a binding does not create translations. Required template labels are validated during rendering/publication: fix missing content rather than hiding it.

Language selector

[[if languages.showSelector]]
<select data-1c-lang aria-label="{{ ui.templateLabels.language }}">
  [[each language in languages.options]]
  <option value="{{ language.code }}">{{ language.label }}</option>
  [/each]
</select>
[[/if]]

The host wires the selector, sets its selected value, and remounts after a language change. Test long translated labels and RTL. Use logical CSS properties such as padding-inline.

<ul>
  [[each link in ui.legalLinks]]
  <li><a href="{{ link.url }}" target="_blank" rel="noopener noreferrer">{{ link.label }}</a></li>
  [/each]
</ul>

Notice links use ui.legalLinks; preferences use ui.details.legalLinks. Preserve each view's authored links. US opt-out URLs and TCF disclosures have framework-specific handling: retain matching supplied content/bindings.

Formatting in localized strings

Ordinary bindings remain text-safe. After rendering, the CMP host recognizes a small BBCode-style formatting vocabulary in translated text:

[b]Important[/b]
[i]Optional processing[/i]
[a href="/privacy"]Privacy policy[/a]
[a action="view:details"]Manage preferences[/a]
[ul][li]One purpose[/li][li]Another purpose[/li][/ul]

Use double quotes for link attributes. These are supported formatting tokens in localized strings, not arbitrary HTML or executable code. Keep formatting simple: nested inline tags are not a general rich-text parser. Use configured/trusted link destinations.

In TCF localized object/string fields, %VENDORS_COUNT% is replaced with the configured vendor count before mounting. For example:

We and our [a action="view:details"]%VENDORS_COUNT% partners[/a] use optional technologies.

The generic compiler/executor renders those strings as text. Formatting conversion and the TCF marker substitution belong to the mounted CMP host; do not expect an isolated template compiler preview to perform those host steps. Array-held strings are not traversed by the marker replacement.

Reactivity

Ordinary bindings produce DOM at mount, not a general reactive expression system. Controlled consent inputs have dedicated synchronization. Language changes remount the view. Use runtime controls rather than manually changing consent maps or browser storage.

On this page