Optional Categories


Optional Categories offers complete freedom to support any third party software that you wish to use, though this form of consent management does require a level of manual set up to ensure no unwanted tracking occurs.

This introductory article aims to outline the general pattern for how you can do this in Cookie Control, by using an analytics and marketing category to integrate Google products such as Google Analytics 4 with Google Consent Mode v2 as an example.

If you are already confident with such software, you may wish to skip to the Final Configuration.

If you are interested in getting started with IAB Europe's Transparency and Consent Framework, please read the article TCF v2.

Anchor point for Integration with GA4 and Google Consent Mode v2

Anchor point for Step 1: Site cleanup

Generally third party software such as analytics, marketing and social sharing tools are included via a <script> element.

As a general rule, we recommend that you do not load scripts of this sort outside of Cookie Control since they may start setting cookies or sending tracking activity from your website before user consent is established.

However, some of the more modern libraries allow you to set default consent signals. This is the case with Google Analytic 4 and Google Consent Mode v2, which outline the following snippet:

<script>
  // Include the following lines to define the gtag() function when
  // calling this code prior to your gtag.js or Tag Manager snippet
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}

  // Call the default command before gtag.js or Tag Manager runs to
  // adjust how the tags operate when they run. Modify the defaults
  // per your business requirements and prior consent granted/denied, e.g.:
  gtag('consent', 'default', {
    'ad_storage': 'denied',
    'ad_user_data': 'denied',
    'ad_personalization': 'denied',
    'analytics_storage': 'denied'
  });
</script>
<!-- Load gtag.js or Tag Manager as normal, e.g.: -->
<script async src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID">
</script>

Anchor point for Step 2: Cookie Categories

The next step is to extend your Cookie Control configuration by adding the property optionalCookies and as many categories as you'd like to present to the user. You can either create categories for each product used - such as Facebook Pixel, Linkedin Insight or Twitter Pixel; or group them by type - such as analytics, or marketing.

To create a category, add a JavaScript Object within optionalCookies containing the following properties:

nameA unique identifier for the category, will be used to store user preference. This value must be a valid cookie name, so special characters such as ()<>@,;:"?={}\/ are prohibited.
labelThe descriptive title assigned to the category and displayed to the user as a heading.
descriptionThe full description assigned to the category and displayed to the user as a paragraph.

In the example scenario, this would be two categories to make users aware analytics and marketing software may be used on the website:

const config = {
    apiKey: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
    product: 'XXX',
    optionalCookies: [
        {
            name: 'analytics',
            label: 'Analytical Cookies',
            description:
                'Analytical cookies help us to improve our website by collecting and reporting information on its usage.',
        },
        {
            name: 'marketing',
            label: 'Marketing Cookies',
            description:
                'We use marketing cookies to help us improve the relevancy of advertising campaigns you receive.',
        },
    ],
}

Anchor point for Step 3: Associate User Action

By adding the above JavaScript Object, users will be able to understand the purpose behind each optional cookie category and will be able to either grant consent, or revoke it via the user interface.

These user actions also need to be associated with the relevant functionality offered by the library you wish to use, which requires extending the JavaScript Object with the following properties:

onAccept

Callback function that will fire on user's opting into this cookie category.

onRevoke

Callback function that will fire on user's opting out of this cookie category.

Typically, this would mean following the third party software's guidance for loading the library as part of the onAccept callback; and following the software's guidance for User Opt-out as part of the onRevoke callback.

In the example scenario, this would mean adding Google's guidance on updating consent state

 optionalCookies: [
    {
        name: 'analytics',
        label: 'Google Analytics',
        description: 'Analytical cookies help us to improve our website by collecting and reporting information on its usage.',
        onAccept: function(){
            gtag('consent', 'update', {
                'analytics_storage': 'granted'
            });
        },
        onRevoke: function(){
            gtag('consent', 'update', {
                'analytics_storage': 'denied'
            });
        }
    },
    {
        name: 'marketing',
        label: 'Google Ad Platforms',
        description: 'We use marketing cookies to help us improve the relevancy of advertising campaigns you receive.',
        onAccept: function(){
            gtag('consent', 'update', {
              'ad_storage': 'granted',
              'ad_user_data': 'granted',
              'ad_personalization': 'granted'
            });
        },
        onRevoke: function(){
            gtag('consent', 'update', {
              'ad_storage': 'denied',
              'ad_user_data': 'denied',
              'ad_personalization': 'denied'
            });
        }
    }
],

Anchor point for Step 4: Protected Cookies

Cookie Control attempts to clean up and remove as many cookies as it can every time a user interacts with the tool in order to respect their current preferences.

To ensure third party software functions correctly, we recommend extending each optional category with the following property:

cookies

The names of the cookies that you wish to protect after a user opts in.

This property expects a JavaScript Array of String values identifying the Cookie Names to protect, though if convenient you may use the an asterisk as a wildcard character at the end of the name to define multiple cookies that share the same prefix.

Again, the specific values needed here will depend on the third party software you wish to use so will need to refer to the respective software's guidance on Cookie Usage.

In the example scenario, this would mean reading Google's Analytics 4 Cookie Usage support article and inputting those relevant to our use case. For instance:

const config = {
    // apiKey and product removed for brevity
    optionalCookies: [
        {
            // name, label and description, onAccept and onRevoke removed for brevity
            cookies: [
                '_ga',
                '_ga*',
                '_gid',
                '_gat',
                '__utma',
                '__utmt',
                '__utmb',
                '__utmc',
                '__utmz',
                '__utmv',
            ],
        },
    ],
}

Please note, older versions of Google Analytics would require a lot more cookies than it's modern equivalent so have included more than is needed in the above example for demonstration purposes. For improved accuracy, please check the documentation for the latest documentation for the version deployed on your site.

Anchor point for Step 5: Final configuration

The final configuration for your optionalCookies should look as follows. The cookies suggested for protection have been incr

optionalCookies: [
    {
        name: 'analytics',
        label: 'Google Analytics',
        description: 'Analytical cookies help us to improve our website by collecting and reporting information on its usage.',
        cookies: ['_ga', '_ga*', '_gid', '_gat', '__utma', '__utmt', '__utmb', '__utmc', '__utmz', '__utmv'],
        onAccept: function(){
            gtag('consent', 'update', {'analytics_storage': 'granted'});
        },
        onRevoke: function(){
            gtag('consent', 'update', {'analytics_storage': 'denied'});
        }
    },
    {
        name: 'marketing',
        label: 'Google Ad Platforms',
        description: 'We use marketing cookies to help us improve the relevancy of advertising campaigns you receive.',
        onAccept: function(){
            gtag('consent', 'update', {'ad_storage': 'granted', 'ad_personalization': 'granted', 'ad_user_data': 'granted'});
        },
        onRevoke: function(){
            gtag('consent', 'update', {'ad_storage': 'denied', 'ad_personalization': 'denied', 'ad_user_data': 'denied'});
        }
    }
],

This guide is meant as an overview of how libraries can be manually integrated with Cookie Control's optional cookie categories. More complex behaviours, such as Google's wait_for_update will often depend on the specifics of each particular site so we would always recommend following the latest documentation and advice of the library you wish to support.

If you have struggled to follow the above, the same functionality is available via our GTM Template which some may find easier to use - though this may not be so easily customised.


Anchor point for Matomo Analytics

Matomo Analytics can be used as an alternative example. The library works in a similar manner as Google's Consent Mode. To make consent required, Matomo users will need to insert the following line at top of their existing Matomo Tracking code, on all their pages.

// require user tracking consent before processing data
_paq.push(['requireConsent']);

They can then configure a category for Matomo cookies with the onAccept and onRevoke properties providing or removing consent as per the visitors request.


Anchor point for Third Party Cookies

Cookie Control (and JavaScript generally) cannot delete third party cookies for browser security reasons. If an optional category enables software, such as Facebook Pixel, Linkedin Insight or Twitter Pixel, that might set third party cookies as part of it's onAccept function, then it is important to add the property thirdPartyCookies as part of the Category definition.

This property expects a JavaScript Array listing the names of all third party vendors enabled by the Category, along with the relevant URL user's need to manually opt out of third party tracking.

thirdPartyCookies

Expects a JavaScript Array with at least one JavaScript Object consisting of the properties name and url. Only applicable if the category will set third party cookies on acceptance.

This property is often required for categories that enable advertising, or functionality related to marketing and whose vendor does not offer any programmatic means to revoke consent.

For instance a category that enables AddThis functionality to share content via various social media channels might be:

const config = {
    // apiKey and product removed for brevity
    optionalCookies: [
        {
            name: 'socialmedia',
            label: 'Social Media Cookies',
            description:
                'We use AddThis to facilitate the convenient sharing of our content with your friends across social media.',
            cookies: ['__atuvc', '__atuvs'],
            onAccept: function () {
                // Add addThis
                let script = document.createElement('script')
                script.src =
                    '//s7.addthis.com/js/300/addthis_widget.js#pubid=XXXXX'
                document.body.appendChild(script)
                // End addThis
            },
            onRevoke: function () {
                // No programmatic opt out behaviour offered by vendor.
                // Requires user action
            },
            thirdPartyCookies: [
                {
                    name: 'AddThis',
                    optOutLink: 'https://www.addthis.com/privacy/opt-out',
                },
            ],
        },
    ],
}

Anchor point for Legitimate Interests

By default, all optional categories require an explicit affirmative user action before a record of consent is issued and the onAccept function is called.

Though it is possible to override this behaviour and enable certain optional categories prior to any user interaction if they may be justified on the grounds of legitimate interests - a more flexible lawful basis for processing data.

If you choose to rely on legitimate interest, then please be aware you are taking on extra responsibility for considering and protecting people’s rights and interests; and must include details of your legitimate interests in your privacy statement. This is unlikely to be the case for most analytics, advertising, or software offered by third party vendors.

Read more from the ICO

To associate an optional category with this form of lawful basis, the Category definition needs to be extended with the property lawfulBasis.

lawfulBasis

Can be either "consent" (default) or "legitimate interest".



If the latter, the UI will show the optional category as enabled, though no record of consent will exist. Users may still object and manually opt out.

For convenience, an optional category defined with this behaviour would be:

const config = {
    // apiKey and product removed for brevity
    optionalCookies: [
        {
            // name, description etc
            lawfulBasis: 'legitimate interest',
        },
    ],
}

Anchor point for CCPA and Geolocation - Pro

By default, Cookie Control requires explicit, affirmative user action before any consent option is enabled. This stricter privacy requirement is due to GDPR and is enforced for those visiting your site from within the EU.

Though, for users accessing your site from outside the EU, it is possible to configure Cookie Control to run in a more flexible privacy model whereby consent options are enabled by default and users simply have the option to withdrawal their consent - so long as you make it convenient for users to find out and object to how you process their personal information.

This opt-out configuration satisfies the California Consumer Privacy Act (CCPA), so is identified within Cookie Control as ccpa mode.

Associating Cookie Control with CCPA behaviour

To enable support for CCPA, your configuration needs to be extended with the properties mode and ccpaConfig, which Cookie Control expects as a JavaScript Object containing the following properties:

description

The text description that introduces your Personal Information Policy.

name

The text label that best describes your Personal Information Policy and is included within the HTML link element.

url

The URL where your Personal Information Policy may be publicly accessed. The HTML link element will try to open in a new tab, so it may point to a PDF document if you wish without closing the user's access to your site.

rejectButton

The text used within the button for objecting to all available options.

updated

The date that your Personal Information Policy was last issued, in the format of dd/mm/yyyy.

For convenience, you can extend your configuration with the following snippet - though please be aware that there are no default values for URL and updated and ccpaConfig will be considered invalid and dismissed if not supplied.

const config = {
    // apiKey and other settings...
    mode: 'ccpa',
    ccpaConfig: {
        description:
            'This may include the website or our third-party tools ' +
            'processing personal data. In the case of your personal data, ' +
            'you may opt out of such activity by using the buttons below. ' +
            'To find out more about the categories of personal information ' +
            'collected and the purposes for which such information will be ' +
            'used, please refer to our',
        name: 'Personal Information Policy',
        url: 'https://www.civicuk.com/',
        updated: '25/05/2018',
        rejectButton: 'Do Not Sell or Share My Personal Information',
    },
}

With pro and multi-site licences, Cookie Control uses geolocation data to assess where each site visitor is accessing your site from. This means if your configuration includes the above, Cookie Control will consider this as the minimal level of privacy required and automatically upgrade to GDPR mode if the site visitor is determined to be accessing your site from within either the UK or European Union (EU).

Please note, if the user has a browser or extension that sends a Global Privacy Control (GPC) signal, Cookie Control will accept this as an intent not to be tracked and prevent automatic tracking from occurring. All categories will default to off even in CCPA mode, unless the user has overwritten this signal by explicitly opting in to a given category on your site.