Introduction
The Enzuzo Cookie Banner provides additional capabilities that can be configured manually, giving full control to the behaviour of the website. This includes categorization and automatic blocking of cookies and third party scripts; per-region banner appearance customization; additional translation options; custom code responses to consent actions; and more.
The window.__enzuzoConfig
Object
Most JavaScript-based configuration is done via window.__enzuzoConfig
, an object which should be defined in a script before our cookie banner is loaded. The object is expected to conform to the following interface:
type EnzuzoConfig = {
callbacks?: Callbacks
cookies?: CookieOpts // Enterprise only
translations?: TranslationOpts // Enterprise only
groups?: GroupOpts[] // Enterprise only
bannerMode?: BannerMode // Legacy; prefer using `regions`.
}
All types referred to above are documented in the sections below. Some functionality is restricted to Enterprise customers only.
Callbacks: Running Code on Consent
You can configure the cookie banner to run custom JS code to handle consent lifecycles.
type EnzuzoConsent = {
analytics: boolean
functional: boolean
marketing: boolean
preferences: boolean
saleOfData?: boolean // SHOPIFY ONLY! Omit otherwise.
}
type Callback = (consent: EnzuzoConsent) => void
type Callbacks = {
acceptSelected?: Callback
acceptAll?: Callback
decline?: Callback
init?: Callback
dismiss?: Callback
doNotSell?: Callback
shown?: Callback
}
window.__enzuzoConfig.callbacks: Callbacks
callbacks.acceptSelected
: Visitor accepts some but not all categoriescallbacks.acceptAll
: Visitor accepts all categoriescallbacks.decline
: Visitor clicks “decline all”callbacks.init
: Cookie banner script is loadedcallbacks.dismiss
: Visitor clicks x/dismiss buttoncallbacks.doNotSell
: Visitor opts out of sale of personal data (Shopify only; see the section titled Do Not Sell Modal below)callbacks.shown
: Cookie banner is shown to the visitor
The following script is an example where the cookie cookie-status-analytics
reflects the consent status of the analytics category.
<script>
function onAnalyticsConsentChange({ analytics, functional, marketing, preferences }) {
const expiry = new Date(Date.now() + 365 * 864e5)
document.cookie = `cookie-status-analytics=${analytics};
expires=${expiry}; path=/; domain=${location.hostname}`
}
function onAcceptSelected({ analytics, functional, marketing, preferences }) {
console.debug('[Enzuzo API]: callbacks.onAcceptSelected', { analytics, functional, marketing, preferences })
onAnalyticsConsentChange({ analytics, functional, marketing, preferences })
}
function onAcceptAll({ analytics, functional, marketing, preferences }) {
console.debug('[Enzuzo API]: callbacks.onAcceptAll', { analytics, functional, marketing, preferences })
onAnalyticsConsentChange({ analytics, functional, marketing, preferences })
}
function onDecline({ analytics, functional, marketing, preferences }) {
console.debug('[Enzuzo API]: callbacks.onDecline', { analytics, functional, marketing, preferences })
onAnalyticsConsentChange({ analytics, functional, marketing, preferences })
}
function onInit({ analytics, functional, marketing, preferences }) {
console.debug('[Enzuzo API]: callbacks.onInit', { analytics, functional, marketing, preferences })
onAnalyticsConsentChange({ analytics, functional, marketing, preferences })
}
window.__enzuzoConfig = {
callbacks: {
acceptSelected: onAcceptSelected,
acceptAll: onAcceptAll,
decline: onDecline,
init: onInit
}
}
</script>
<script src="https://app.stage.enzuzo.com/scripts/cookiebar/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeeeee"></script>
The argument passed to each callback contains information about the categories consented to by the user, conforming to the EnzuzoConsent
type defined above.
Banner Mode Override
You can use the following script to override the banner mode determined by your regional settings. The script must be included before the cookie banner embed code. For Enterprise customers, note that this will override any banner modes specified via groups
(see the section titled Region-Based Blocking, Banner Mode, and Appearance Configuration). This is a legacy option; groups
should be preferred.
<script>
window.__enzuzoConfig = window.__enzuzoConfig ?? {}
window.__enzuzoConfig.bannerMode = 'dontshow' // or 'optin', 'optout', 'tcf'
</script>
Auto-Blocking
Script auto-blocking can be enabled with the auto-blocking
script attribute on the Enzuzo cookie banner script (which, namely, should be in the <head>
section of the HTML, placed before any scripts that you want to block; the cookie banner cannot block scripts that are run before the cookie banner itself). Here is an example:
<script auto-blocking="true" src="https://app.enzuzo.com/scripts/cookiebar/c4b59d26-1d9c-11ed-bef4-6b8ef0dd69e3"></script>
Setting
auto-blocking="true"
will block all scripts by default, unless their category has been allowed.Setting
auto-blocking="allow"
will allow uncategorized scripts to run without being blocked.
Similarly, cookie auto-blocking can also be enabled with the auto-blocking-cookies
script attribute, which behaves the same way as the auto-blocking
attribute.
Warning: We strongly discourage the use of cookie auto-blocking; we recommend using script blocking instead, as it will not risk breaking any scripts that might depend on the browser's cookie interface.
Categorizing Third-Party Scripts
For each script, you can define their category and description (optionally locale-specific). The following is a list of attributes that can be defined for each script.
Attribute Name | Description |
ez-type | The type — should always be "cb" for the cookie banner. |
ez-cb-id | Script ID — can be anything unique |
ez-cb-cat | The category of the script. Should be one of "functional", "marketing", "analytics", or "preferences". We may support additional categories in the future. |
ez-cb-desc | The description for this script |
ez-cb-desc-{{locale}} | Locale specific description, such as ez-cb-desc-fr for French. |
Here are is an example of loading Google Analytics.
<script async ez-type="cb" ez-cb-id="ga" ez-cb-cat="analytics" ez-cb-desc="Google Analytics is a web analytics service offered by Google that tracks and reports website traffic" src="https://www.googletagmanager.com/gtag/js?id=GA_TRACKING_ID"></script>
Google Analytics is a web analytics service offered by Google that tracks and reports website traffic.
Multiple categories: If needed, a script can be given multiple categories. A comma (,
) is used to mean "or", while a plus (+
) is used to mean "and".
For example, to specify that a script should only run if consent is given for marketing AND analytics purposes, set ez-cb-cat="marketing+analytics"
. To specify that a script should run if consent is given for marketing OR analytics purposes (i.e., at least one of the two), set ez-cb-cat="marketing,analytics"
.
Basic Appearance Options
Using the following script, you will be able to configure the consent button options depending on the banner consent mode. The script must be included before the cookie banner embed code. You can define what buttons to hide based on which consent mode. The following script will hide the accept and decline buttons when the consent mode is set to opt-out or don't show. For Enterprise customers, note that this will override any region-based banner appearance specified via groups[number].appearance
(see the section titled Advanced Appearance Options). This is a legacy option; usage should be avoided.
<script>
// NB: This uses `window.__enzuzo`, NOT `window.__enzuzoConfig`.
window.__enzuzo = window.__enzuzo ?? {};
window.__enzuzo.hideButtons = window.__enzuzo.hideButtons ?? {};
window.__enzuzo.hideButtons = { accept: ['optout', 'dontshow'], decline: ['optout', 'dontshow'] };
</script>
Custom Cookie Preferences Button
Adding the data-ez-show-preferences
attribute to a DOM element will open the cookie preferences when that element is clicked.
<div class="btn btn-primary" ez-show-preferences>
Show Preferences
</div>
Do Not Sell Modal (Shopify only)
We offer a "Do Not Sell" modal for Shopify that hooks into Shopify's API. A visitor can use this to opt out of the sale of their data. It can be accessed via a link to #do_not_sell_optout
OR by invoking window.__enzuzoApi.doNotSell.show()
.
Note: The purpose of this modal is different than the Do Not Sell page. The Do Not Sell page allows existing customers to file a request to opt-out of the sale of their data, i.e., it will be the site administrator's responsibility to take action on requests submitted this way. This modal, on the other hand, is for any visitor who wishes to opt out of the sale of their data immediately, having the request handled via Shopify's consent API.
Enterprise Features
The features listed below are available in the Enterprise plan.
Translations (enterprise)
Locale-dependent translation strings can be specified and used in conjunction with groups[number].appearance
(see the section titled Region-Based Blocking, Banner Mode, and Appearance Configuration).
type TranslationOpts = {
fallbackLocale: string // e.g. 'en', 'en-US', ...
// Locale to fall back to if no applicable locale is found
forceLocale?: string
// Forces a given locale, overriding visitors' preferred languages
strings: Record<string, Record<string, string>>
// Map from translation string key to map from locale to text
}
window.__enzuzoConfig.groups[number].appearance: TranslationOpts
Example usage follows:
window.__enzuzoConfig = {
/* other settings... */
translations: {
fallbackLocale: 'en',
strings: {
'ACCEPT_BUTTON': {
'en': 'Accept',
'fr': 'Accepter',
'pt-BR': 'Aceitar'
},
'DECLINE_BUTTON': {
'en': 'Decline',
'fr': 'Refuser',
'pt-BR': 'Declínio'
},
'OK_BUTTON': {
'en': 'OK',
'fr': "D'accord",
'pt-BR': 'OK'
}
}
}
}
Region-Based Blocking, Banner Mode, and Appearance Configuration (enterprise)
Cookie blocking, script blocking, banner mode, and banner appearance can be defined per-region via the groups
property of the window.__enzuzoConfig
configuration object, which should conform to the following interface:
type Stroolean = boolean | 'true' | 'false'
type BlockingOpts = {
scripts?: 'allow' | 'deny' | Stroolean
// 'false' | false: No script blocking (default)
// 'allow': Allow uncategorized scripts to run without being blocked
// 'true' | true | 'deny': Block scripts unless their category has been allowed
cookies?: 'allow' | 'deny' | Stroolean
// 'false': No cookie blocking
// 'allow': Allow uncategorized cookies (default)
// 'true' | true | 'deny': Block cookies unless their category has been allowed
bodyLock?: Stroolean
// 'true' | true: Prevent scrolling until user accepts or declines cookies
// 'false' | false: Allow scrolling (default)
}
type Region = {
worldwide?: Stroolean
// Applies if no other region applies
area?: 'EU'
// Applies if user is in this area and there is no more specific applicable country
country?: string // 'US', 'CA', etc...
// Applies if user is in this country and there is no more specific applicable state
state?: string // 'NJ', 'QC', etc...
// Applies if user is in this state and the above country
}
type GroupOpts = {
regions: Region[] // regions to apply this configuration to
mode?: 'optin' | 'optout' | 'dontshow' | 'tcf'
// Banner mode
managerIcon?: Stroolean
// Whether or not to show the floating consent options button
blocking?: BlockingOpts
// Blocking options for this region
appearance?: AppearanceOpts
// Button configuration per-region
}
window.__enzuzoConfig.regions: RegionOpts[]
Note: A Region
object should be a superset of exactly ONE of the types { default: true | 'true' }
, { worldwide: true | 'true' }
, { area: 'EU' }
, and { country: string; state?: string }
. If the provided object contains any two subobjects each satisfying distinct types in this set, the provided object is invalid.
Blocking Options (enterprise)
The BlockingOpts
interface defines cookie blocking, script blocking, and scroll lock behaviour for the object's containing region. For example, the following script will set the banner mode to opt-in for all regions that do not specify their own banner mode, and, for Quebec, enable script blocking, enable cookie blocking while allowing uncategorized cookies, and prevent interacting with the website until the user has interacted with the banner:
<script>
window.__enzuzoConfig = {
groups: [
{
regions: [{ worldwide: true }],
mode: 'optin',
},
{
regions: [{ country: 'CA', state: 'QC' }],
mode: 'optin',
blocking: {
scripts: 'deny',
cookies: 'allow', // discouraged: see warning below
bodyLock: true,
},
},
],
}
</script>
Scripts can be categorized as described in the section titled Categorizing Third-Party Scripts above. Cookies can be categorized either via the admin app or via JavaScript — for the latter, see the section titled Cookie Categorization below.
Warning: We strongly discourage the use of cookie auto-blocking; we recommend using script blocking instead, as it will not risk breaking any scripts that might depend on the browser's cookie interface.
Advanced Appearance Options (enterprise)
The AppearanceOpts
interface defines banner appearance for the object's containing region, including text, links, and interaction behaviour. It is read from window.__enzuzoConfig.groups[number].appearance
and should conform to the following interface:
type AppearanceOpts = {
banner?: {
bodyLabel?: string // Translation string key
buttons?: {
first?: {
label: string // Translation string key
action: 'accept-all' | 'decline' | 'dismiss'
} | null
second?: {
label: string // Translation string key
action: 'accept-all' | 'decline' | 'dismiss'
} | null
dismiss?: {
action: 'accept-all' | 'decline' | 'dismiss'
} | null
prefCenterButtonLabel?: string | null // Translation string key
privacyPolicy?: {
label: string // Translation string key
urlLabel: string // Translation string key
} | null
}
}
doNotSell?: {
bodyLabel?: string // Translation string key
}
}
window.__enzuzoConfig.groups[number].appearance: AppearanceOpts
Note that AppearanceOpts
requires the use of translation strings defined via window.__enzuzoConfig.translations
.
Here's a practical example that sets the EU/EEA to be an opt-in region with two buttons ("Accept all") and "Decline"), California to be an opt-out region with only one button ("OK"), and the rest of the world to have the banner hidden.
<script>
window.__enzuzoConfig = {
translations: {
fallbackLocale: 'en',
strings: {
'BANNER_OK': { en: 'OK' },
'BANNER_ACCEPT_ALL': { en: 'Accept all' },
'BANNER_DECLINE': { en: 'Decline' },
},
},
groups: [
{
regions: [{ worldwide: true }],
mode: 'dontshow'
},
{
regions: [{ area: 'EU' }],
mode: 'optin',
appearance: {
banner: {
buttons: {
first: {
label: 'BANNER_ACCEPT_ALL',
action: 'accept-all'
},
second: {
label: 'BANNER_DECLINE',
action: 'decline',
}
}
}
}
},
{
regions: [{ country: 'US', state: 'CA' }],
mode: 'optout',
appearance: {
banner: {
buttons: {
first: {
label: 'BANNER_OK',
action: 'accept-all'
},
second: null
}
}
}
}
]
}
</script>
More details about particulars for appearances/translations:
Unspecified properties will fall back on defaults. Explicitly specifying
null
will hide something. For example,country: 'CA', appearance: { banner: { buttons: { second: null } } }
will hide the second button, and the banner will otherwise look normal.If the appearance property is present, any analogous properties in its scope that are specified via the admin app will be ignored — the visibility, behaviour, and text of the buttons are completely determined by the property if present.
Translation string keys will be sourced with respect to the user's locale/language (e.g., for English users, they may be sourced from
window.__enzuzoConfig.translations.strings[string]['en']
), falling back to thefallbackLocale
if not present.If a visitor is not in any applicable regions at all (and, namely, no
default: true
region was set), the appearance settings for that visitor will fall back to any relevant rules specified in the admin app.Usual precedence rules apply — see example below:
Suppose the visitor is located in Québec, Canada with preferred locale
en-CA
(or justen
). The banner text reads "Something about Québec Law 25". There are two buttons: an "OK" button that dismisses the banner and a "Decline" button (specified for Quebec only). A "dismiss"/"x" button is not shown since it was not specified for Québec. A privacy policy link is shown, labelled "Privacy Policy" and pointing to "https://example.com/law25-privacy-policy-en
". A button to open the preference center is shown, labelled "Manage cookies".
<script>
// Suppose the visitor is located in Québec, Canada
window.__enzuzoConfig = {
/* other settings... */
translations: {
fallbackLocale: 'en',
strings: {
'DEFAULT_BANNER_TEXT': {
'en': 'Lorem Ipsum',
'fr': 'Très bien fait',
},
'LAW25_BANNER_TEXT': {
'en': 'Something about Québec Law 25',
},
'GDPR_BANNER_TEXT': {
'en': 'Something about GDPR',
},
'CCPA_BANNER_TEXT': {
'en': 'Something about CCPA',
},
'MANAGE_COOKIES': {
'en': 'Manage cookies',
'fr': 'Gérer les cookies',
},
'LABEL_OK': {
'en': 'OK',
'fr': "D'accord",
},
'LABEL_DECLINE': {
'en': 'Decline',
'fr': 'Refuser',
},
'LABEL_ACCEPT': {
'en': 'Accept',
'fr': 'Accepter'
},
'PRIVACY_POLICY': {
'en': 'Privacy Policy',
'fr': 'Politique de Confidentialité',
},
'PRIVACY_POLICY_URL': {
'en': 'https://example.com/privacy-policy-en',
'fr': 'https://example.com/privacy-policy-fr',
},
'LAW25_PRIVACY_POLICY_URL': {
'en': 'https://example.com/law25-privacy-policy-en',
'fr': 'https://example.com/law25-privacy-policy-fr',
},
},
},
groups: [
{
regions: [{ worldwide: true }],
mode: 'optout'
appearance: {
banner: {
bodyLabel: 'DEFAULT_BANNER_TEXT',
buttons: {
first: { label: 'LABEL_OK', action: 'dismiss' },
prefCenterButtonLabel: 'MANAGE_COOKIES',
privacyPolicy: {
label: 'PRIVACY_POLICY',
urlLabel: 'PRIVACY_POLICY_URL',
},
},
},
},
},
{
regions: [{ country: 'CA', state: 'QC' }],
mode: 'optin'
appearance: {
banner: {
bodyLabel: 'LAW25_BANNER_TEXT',
buttons: {
first: { label: 'LABEL_OK', action: 'dismiss' },
second: {
label: 'LABEL_DECLINE',
action: 'decline',
},
prefCenterButtonLabel: 'MANAGE_COOKIES',
privacyPolicy: {
label: 'PRIVACY_POLICY',
urlLabel: 'LAW25_PRIVACY_POLICY_URL',
},
},
},
},
},
{
regions: [{ area: 'EU' }],
mode: 'optin'
appearance: {
banner: {
bodyLabel: 'GDPR_BANNER_TEXT',
first: {
label: 'LABEL_ACCEPT',
action: 'accept-all',
},
second: {
label: 'LABEL_DECLINE',
action: 'decline',
}
dismiss: {
visible: true,
action: 'dismiss',
}
}
}
},
{
regions: [{ country: 'US', state: 'CA' }],
appearance: {
banner: {
bodyLabel: 'CCPA_BANNER_TEXT',
},
},
}
],
}
</script>
Cookie Categorization (enterprise)
As well as using the admin app, cookies can also be categorized via the cookies
property of window.__enzuzoConfig
. If this is set, any cookie categorization specified in the admin app will be completely ignored. The cookies
property should conform to the following interface:
type ConsentCategory =
| 'functional'
| 'marketing'
| 'analytics'
| 'preferences'
type Cookie = {
name: string
// Cookie name; NOT translated
hostname: string
// Originating hostname
scriptId?: string
// Value of ez-cb-id attribute specified on an associated script tag
category: ConsentCategory | ConsentCategory[] | ConsentCategory[][]
// 1. Single consent category
// 2. Disjunction of consent categories
// e.g., ['marketing', 'analytics'] enables on marketing OR analytics consent
// 3. Disjunction of conjunction of consent categories
// e.g. [['marketing', 'analytics'], ['preferences']] enables on consent to
// preferences OR on consent to both marketing and analytics.
party: 'first' | 'third'
expiry: 'persistent' | 'session' | number
// Number represents milliseconds until expiry
description: string
// Translation string key -- see section on Translations
}
type CookieOpts = {
cookies?: Cookie[]
expireDeclineAfter?: number
// If specified, a "decline" will expire after this many days,
// after which the visitor will again be shown the cookie banner and
// asked for their consent/preferences.
}
window.__enzuzoConfig.cookies: CookieOpts
Here is an example for categorization of two different cookies:
<script>
window.__enzuzoConfig = {
cookies: {
cookies: [
{
name: '__cfruid',
hostname: 'cloudflare.com',
category: 'functional',
party: 'third',
expiry: 'persistent',
description: 'Cloudflare',
},
{
name: 'visitor_id',
hostname: 'example.com',
category: 'analytics',
party: 'first',
expiry: 15770000000,
description: 'Visitor ID',
},
],
},
}
</script>