Consent Manager
Installation
Step 1. Define the ConsentManagerConfig function (or object) to configure the widget:
<script type="text/javascript">
window.ConsentManagerConfig = () => ({
country: 'US',
env: 'prod',
target: '#consent-manager-widget'
});
</script>
Step 2. Add the target container for the banner and preference center:
<div id="consent-manager-widget"></div>
Step 3. Add the widget script tag to your index.html file, after your target element and configuration snippet. The script must be loaded as an ES module:
<script type="module" src="https://consent.chick-fil-a.com/consent-manager.js"></script>
That's it! Open your site in an Incognito tab to see the cookie banner appear.
Performance Considerations
The Consent Manager Widget is designed to be easy to install, so it automatically downloads React and other dependencies on startup. This works great for most static websites, but what about websites that happen to use React?
For these sites, React dependencies would be downloaded twice, which could negactively impact performance. The Consent Manager widget supports preloading dependencies to address this scenario.
To preload dependencies, update your config to include a new dependencies object. Here's an example:
<script type="module">
const dependencies = loadDependencies();
window.ConsentManagerConfig = () => ({
country: 'US',
env: 'prod',
target: '#root',
dependencies,
})
async function loadDependencies() {
const [react, reactDom, reactDomClient, reactJsxRuntime] = await Promise.all([
import('https://esm.sh/[email protected]'),
import('https://esm.sh/[email protected]'),
import('https://esm.sh/[email protected]/client'),
import('https://esm.sh/[email protected]/jsx-runtime'),
]);
return {
react,
reactDom,
reactDomClient,
reactJsxRuntime,
}
}
</script>
Reference
SDK Methods
The window.ConsentManager object exposes a simple JavaScript SDK with the following methods:
| Method | Description |
|---|---|
| openPreferenceCenter() | Opens the Consent Manager Preference Center UI, allowing users to review and update their consent preferences. |
| refreshConfig() | Reads the latest config from window.ConsentManagerConfig and re-renders the UI. |
Installation Options
The window.ConsentManagerConfig property is used to configure the installation for your website. It can be a Config object or a function that returns one.
The Config object supports the following properties:
| Property | Type | Required | Description |
|---|---|---|---|
| country | 'US' | 'CA' |
Yes | The country code that determines localization and applicable consent regulations. |
| env | 'prod' | 'qa' |
No | The environment in which the Consent Manager is running. Defaults to 'prod' if not specified. |
| target | HTMLElement | string |
Yes | The DOM element or selector where the Consent Manager widget will be rendered. |
| user | User |
No | The user information object, containing authentication and identification details. |
| dependencies | Dependencies |
No | An object containing React, ReactDom, and other required dependencies. |
| adapter | Adapter |
No | Custom functions for reading and writing consent preferences. When both getPreferences and setPreferences are provided, they replace the default consent storage behavior. |
The User object supports the following required properties:
| Property | Type | Description |
|---|---|---|
| cfaId | string |
The user's Chick-fil-A ID. |
string |
The user's email address. | |
| accessToken | string |
The user's access token for API authentication. |
The Dependencies object supports the following required properties:
| Property | Type | Description |
|---|---|---|
| react | module |
The react module |
| reactDom | module |
The react-dom module |
| reactDomClient | module |
The react-dom/client module |
| reactJsxRuntime | module |
The react/jsx-runtime module |
The Adapter object supports the following required properties:
| Property | Type | Description |
|---|---|---|
| getPreferences | () => Promise<CookiePreferences | undefined> |
Returns the current consent choices, or undefined if the user has not set preferences yet. Keys are cookie category IDs; values are whether each category is allowed. |
| setPreferences | (preferences: CookiePreferences) => Promise<void> |
Persists the user’s consent choices when they save from the banner or preference center. |
The CookiePreferences object is a Record<string, boolean>, where each key is a category ID and each value indicates if tracking is opted in or out.
Classes and Test IDs
You can customize the banner and preference center appearance using CSS. Each element has a data-testid attribute and class that are easy to target in your stylesheet.
| Component | Test ID | Classes |
|---|---|---|
| Modal | consent-manager-modal | .consent-manager .consent-manager-modal |
| Modal Footer | consent-manager-modal-footer | .consent-manager-modal-footer |
| Modal Save | consent-manager-modal-save | .consent-manager-modal-action |
| Modal Reject All Button | consent-manager-modal-reject-all | .consent-manager-modal-action |
| Modal Accept All Button | consent-manager-modal-accept-all | .consent-manager-modal-action |
| Banner | consent-manager-banner | .consent-manager .consent-manager-banner |
| Banner Footer | consent-manager-banner-footer | .consent-manager-banner-footer |
| Banner Open Button | consent-manager-banner-open-preferences | .consent-manager-banner-action |
| Banner Reject All Button | consent-manager-banner-reject-all | .consent-manager-banner-action |
| Banner Accept All Button | consent-manager-banner-accept-all | .consent-manager-banner-action |
Note: be sure to target the attribute data-testid (e.g. [data-testid="consent-manager-modal"]) for the Test ID values listed above.
Server-Side Configuration
The Consent Manager's behavior, categories, and text are configured by a LaunchDarkly flag named consent-manager-config. LaunchDarkly's advanced targeting allows different configuration options to be specified based on website context, such as country, environment, is_webview, etc.
The flag value is a single JSON object. It supports the following top-level properties:
| Property | Type | Description |
|---|---|---|
| enabled | boolean |
Master kill-switch. When false, the widget renders nothing and the adapter is a no-op. Use this to fully disable the consent manager for a country/environment/user segment. |
| banner | Banner |
Copy and button labels for the cookie banner. See Banner. |
| behaviors | Behaviors |
Controls when the banner is shown and how it responds to user interaction. See Behaviors. |
| categories | Category[] |
The list of cookie categories surfaced in the preference center. Order is preserved. See Category. |
| optOutSignal | { content?: RichContent } |
Copy displayed when the browser sends an opt-out signal such as Global Privacy Control. See Rich Content. |
| preferenceCenter | PreferenceCenter |
Copy, labels, and "About" content for the preference center modal. See Preference Center. |
Banner
| Property | Type | Description |
|---|---|---|
| content | RichContent |
Main banner copy. See Rich Content. |
| acceptAllLabel | string |
Label for the "Accept All" button. |
| rejectAllLabel | string |
Label for the "Reject All" button. |
| openPreferencesLabel | string |
Label for the button that opens the preference center. |
Behaviors
| Property | Type | Default | Description |
|---|---|---|---|
| displayBanner | 'initially' | 'always' | 'never' |
'initially' |
'initially' shows the banner until the user sets preferences. 'always' shows it on every visit. 'never' hides it on every visit. Note: default preferences are set based on requireConsent, and the openPreferenceCenter() still opens the modal regardless of this setting. |
| outsideClick | 'persist' | 'dismiss' | 'accept' | 'reject' |
'dismiss' |
What happens when the user clicks outside the banner. 'persist' keeps it visible. 'dismiss' closes it without changing preferences. 'accept' / 'reject' close it and save the corresponding preferences. |
| requireConsent | boolean |
true |
When true, non-essential categories are opt-in (everything rejected until the user accepts). When false, categories are opt-out (everything accepted until the user rejects). Passed through to the adapter. |
Category
Each entry describes one togglable cookie category in the preference center.
| Property | Type | Description |
|---|---|---|
| groupId | string |
Unique identifier for the category. Used as the key in the CookiePreferences object and published to dataLayer as part of OneTrustGroupsUpdated / CfaConsentGroupsUpdated events. |
| name | string |
Display name shown in the preference center. |
| description | string |
Description shown under the category name in the preference center. |
| alwaysActive | boolean |
When true, the category is locked on and cannot be toggled by the user (typical for strictly-necessary cookies). The preference center shows the alwaysActiveLabel instead of a switch. Takes precedence over honorsGpcSignal. |
| honorsGpcSignal | boolean |
When true, the category is automatically disabled for visitors whose browsers send a Global Privacy Control signal. Ignored when alwaysActive is true. Defaults to false (the category ignores GPC). |
Preference Center
| Property | Type | Description |
|---|---|---|
| title | string |
Heading displayed at the top of the preference center modal. |
| aboutContent | RichContent |
Body copy for the "About" section. See Rich Content. |
| aboutLabel | string |
Label for the button that expands the "About" section. |
| aboutLink | { href?: string; text?: string } |
Optional external link shown in the "About" section. |
| alwaysActiveLabel | string |
Label shown next to categories with alwaysActive: true (e.g. "Always Active"). |
| optOutLabel | string |
Label shown next to categories with honorsGpcSignal: true when navigator.globalPrivacyControl is enabled (e.g. "Opt-out Preference Honored"). |
| acceptAllLabel | string |
Label for the "Accept All" button. |
| rejectAllLabel | string |
Label for the "Reject All" button. |
| saveLabel | string |
Label for the "Save" button that persists the user's current selections. |
Rich Content
The banner.content, optOutSignal.content, and preferenceCenter.aboutContent properties all accept RichContent, which is either:
- A plain
string - An array of
stringvalues and/orTextBlockobjects.
Each TextBlock supports:
| Property | Type | Description |
|---|---|---|
| type | 'text' |
Discriminator. Currently only 'text' is supported. |
| text | string |
The text to display. |
| href | string |
When set, the block is rendered as a link that opens in a new tab. |
| annotations | { bold?: boolean; italic?: boolean; underline?: boolean } |
Optional inline styling. |
Example variation
{
"enabled": true,
"banner": {
"content": [
"We use cookies to give you the best experience on our site. ",
{ "type": "text", "text": "Learn more", "href": "https://www.chick-fil-a.com/privacy" },
"."
],
"acceptAllLabel": "Accept All",
"rejectAllLabel": "Reject All",
"openPreferencesLabel": "Cookie Settings"
},
"behaviors": {
"displayBanner": "initially",
"outsideClick": "dismiss",
"requireConsent": true
},
"categories": [
{
"groupId": "C0001",
"name": "Strictly Necessary Cookies",
"description": "These cookies are required for the site to function.",
"alwaysActive": true
},
{
"groupId": "C0002",
"name": "Performance Cookies",
"description": "These cookies help us measure and improve site performance.",
"honorsGpcSignal": true
}
],
"optOutSignal": {
"content": "Your browser is sending a Global Privacy Control signal. We've automatically opted you out of non-essential cookies."
},
"preferenceCenter": {
"title": "Cookie Preferences",
"aboutContent": ["When you visit our site, we may store or retrieve information on your browser…"],
"aboutLabel": "About Cookies",
"aboutLink": { "text": "Privacy Policy", "href": "https://www.chick-fil-a.com/privacy" },
"alwaysActiveLabel": "Always Active",
"acceptAllLabel": "Accept All",
"rejectAllLabel": "Reject All",
"saveLabel": "Confirm My Choices"
}
}