How to deal with Cookies

Cookie Consent with Silverstripe CMS

How to deal with Cookies and GDPR for your Silverstripe CMS Site? There are various methods and things to consider, so let´s have a closer look.

Cookies. When using websites or web applications as well as when developing websites, there is no getting around them.

Cookies are small text files which are created to store individual user data: for example, information about the user session, an analysis of user behaviour, the preferred language on a website and much more.

Due to the sensitivity of the stored data and legal data protection regulations (GDPR), every website owner is advised to address this topic.
Because cookies are utilized on almost every website, a website owner must inform visitors accordingly when tracking, advertising or other types of cookies are in use.

Types of cookies

There are different types of cookies. However, in this context, the distinction between essential and non-essential cookies is critical.

A cookie is essential when it is absolutely technically required for the use of the website to work. Examples are session cookies or shopping cart cookies which do not pass along data.

Non-essential cookies are, for example, cookies which are used to track user behaviour, advertising cookies or cookies from social medial plugins. These cookies are not necessary for the primary use of a website, and often in these cases, the data is processed by external third-party providers.

This means that if, for example, Google Analytics is implemented or a YouTube video is embedded in a website (unless the privacy enhanced mode without cookies is applied), corresponding non-essential cookies are used.

Cookie consent or cookie notice?

Depending on the country where the website is operated, laws vary somewhat, and the relevant rulings and guidelines are not always entirely clear.

For our purposes, we assume that we are dealing with a location in the EU or non-European companies are processing data from EU citizens. Therefore, we want to be compliant with GDPR. Namely, the explicit consent (or “opt in”) of the visitor occurs before non-essential cookies are allowed to be implemented and possibly store personal data.
Without this consent, the website may not use any non-essential cookies. This method is commonly known as “cookie consent”.

Many websites still display a cookie notice (normally as “cookie bar”), which merely informs the user that cookies are being used. Consent is waived, cookies are used, and the user is not required to click or confirm anything.
However, we consider this method more as a “middle path” which is associated with risks.

In this article, we describe the cookie consent method, as it is currently the most legally secure and generally recommended method.

If uncertainties arise, it is best to consult with an attorney or the company’s legal department. We cannot and do not want to provide any legal advice here; rather, we are more concerned with the common options for implementing this method.

Cookie consent with Silverstripe CMS

Okay – we are working on a solution which:

  • gives the user the option of actively accepting or rejecting cookies.
  • ensures that no data is transferred prior to obtaining consent.
  • allows for the management of corresponding cookie descriptions and also possibly cookie categories. 

The basic installation of Silverstripe CMS does not include a cookie solution. This is actually a good thing. On the one hand, the core remains lean and on the other hand, a solution can be chosen that meets individual requirements. 
There are many methods of integrating a cookie solution – to this end, let’s take a closer look at the following options.

  1. Module
    A Silverstripe module supplements the functionality of the CMS. Modules are typically installed via Composer and end up in the /vendor directory.
  2. JavaScript library
    The cookie solution is integrated using a JavaScript library.
  3. External services
    The cookie solution is integrated via an external platform (usually for a fee). 

Cookie consent integration using a Silverstripe module

A module adds a certain functionality to the CMS. The installation and configuration are normally quite simple. Likewise, certain parts of a module can be customised or extended while remaining updateable.
Further reading on how modules can be developed and installed can be found here.

This are a number of different cookie modules. For our purposes, I would like to examine the following modules in more detail:

Silverstripe Klaro! consent manager

https://github.com/lerni/klaro-cookie-consent

This module implements the open-source version of the “Klaro” consent management platform from KIProtect.

The installation is done via Composer.
composer require lerni/klaro-cookie-consent

After that, run dev/build.

Now the module is installed. In the backend under Settings > Cookie Consent, the module can be activated, and corresponding changes can be made.
The module also automatically creates cookie categories, and additional categories can be created as needed.

Now it must be verified that external JavaScript code is not executed until usage is confirmed by the user.

Simply replace src with data-src, change the type attribute to text/plain and assign a data-name which corresponds to the name of the application.

<script type="text/plain"
    data-type="text/javascript"
    data-name="optimizely"
    data-src="https://cdn.optimizely.com/js/10196010078.js">
</script>

Details can also be found in the Readme of the module.

Furthermore, a compatible integration of Google Analytics & Tag Manager can be done via the following module:
https://github.com/lerni/googleanalytics

Finished – now a cookie notice should appear on the website.

If you want a decision from the user instead of a notification from a cookie consent window, you can set the mustConsent parameter to true.
The module stores the configuration in the KlaroConfigController.ss file, which can be found here: /vendor/lerni/klaro-cookie-consent/templates/Kraftausdruck/Controller/KlaroConfigController.ss

This file has to copied to your own theme, to make changes:
/themes/mytheme/templates/Kraftausdruck/Controller/KlaroConfigController.ss

A line can be added there as follows:
mustConsent: true,

After a dev/build, a cookie consent window will be displayed instead of a cookie notice.

Styling can be customised as desired, see SCSS example:

html .klaro {
    /* cookie-notice at page bottom */
    .cookie-notice,
    .cookie-notice:not(.cookie-modal-notice) {
        background-color: green;
    }


    /* cookie-modal with cookie settings */
    .cookie-modal {
        .cm-modal.cm-klaro {
            background-color: blue;
        }
    }
}

An example with further class specifications can be found here:
https://github.com/lerni/klaro-cookie-consent#styling

At the time of this article, the module “Silverstripe Klaro! Consent Manager” version 3.x-dev and Silverstripe CMS 4.10.0 were used.

Silverstripe cookie consent

https://github.com/TheBnl/silverstripe-cookie-consent

Another cookie consent module with a slightly different structure: the cookie categories (and their selection for consent) occur on a separate page and not directly in the consent window.

Here the installation is also carried out via Composer:

composer require bramdeleeuw/cookieconsent

After that, run dev/build.

Now this template must be included in your Page.ss:
<% include CookieConsent %>

The cookies and cookie categories can be configured using yml: 

Broarm\CookieConsent\CookieConsent:
  cookies:
    Necessary:
      local:
        - CookieConsent
        - ShowPopUp
    Marketing:
      ads_marketingcompany_com:
        - _track
    Analytics:
      local:
        - _ga
        - _gid

Cookie settings can now be made in the backend under Settings -> Cookie Consent. Other cookies can also be created.

In the code, “Consent” can be queried as follows:

if (CookieConsent::check('Analytics')) {
    // include google analytics
}

or also directly in the template:

<% if $CookieConsent(Analytics) %>
      $GoogleCode.RAW
<% end_if %>

The module automatically creates the appropriate pages in the site tree – among others the CookiePolicyPage which shows the cookies and the cookie categories.

Styling can be easily individualised, see SCSS example:

.cookie-consent {
    background-color: green;

    .cookie-consent__buttons {
        .cookie-consent__button--accept {
            font-weight: bold;
        }
    }
}

Details regarding installation and configuration can be read here:
https://github.com/TheBnl/silverstripe-cookie-consent

At the time of this article, the module “Silverstripe Cookie Consent” version 3.1.0 and Silverstripe CMS 4.10.0 were used.

Cookie Consent Integration via JS library

Depending on requirements and developer skills, this issue can also be solved via your own frontend – for example, with a simple JavaScript library such as “cookieconsent”, the freely available JavaScript library from Osano’s consent management platform.

Or a somewhat more extensive library including cookie categories like “cookieconsent” from Orest Bida.

cookieconsent / osano

https://github.com/osano/cookieconsent

The configuration of most parameters is carried out via the JavaScript API of the module.
For example, the execution of the code after the user’s consent can be achieved as follows:

onInitialise: function (status) {
    if (this.hasConsented()) {
        // execute JS Code
    } else {
        // out
    }
},

Basic formatting (e.g., colours) and layout options can be set using the JavaScript configuration or also created via SCSS – see example.

.cc-window.cc-banner,
.cc-window.cc-floating{
    background-color: white;
    padding: 2rem;
    .cc-allow {
        border: 2px solid black;
    }

    .cc-deny {
        border: none;
    }
}

cookieconsent / orstbida

https://github.com/orestbida/cookieconsent

Similarly, much of the configuration is done using the JavaScript API.
The execution of the code after the user's consent can be achieved, for example, as follows:

cookieconsent.run({
    // ...
    page_scripts: true
    // ...
});

Then in the template, type="text/plain" and data-cookiecategory="<category>" can be set for each script tag:

<script type="text/plain" data-cookiecategory="analytics" src="analytics.js" defer></script>

<script type="text/plain" data-cookiecategory="ads">
    console.log('"ads" category accepted');
</script>

Here data-cookiecategory must be a valid category within the configuration.

For design customisation, there are many options available in the JavaScript configuration. Furthermore, many ready-made themes (dark, light, etc.) are also offered, see:
https://orestbida.com/demo-projects/cookieconsent/

Or, of course, via your own SCSS, for example:

.cc_div {
    #c-bns{
        button#c-p-bn{
            //accept button
            border:  4px solid black;
        }
    }
}

There are also many other libraries available for all tastes.

External Cookie Consent services

There are numerous providers of cookie consent tools, such as consent management platforms, which can be easily integrated into a website, for example: 

The applications range from simple tools to comprehensive services including analytics and reporting functions, extensive dashboards, monitoring functions and much more.

As a rule, these platforms are fee-based, usually via a subscription model.

Integration is usually carried out via JavaScript snippets which can be integrated into the website. Customisation is limited, of course, not only in terms of design but also when dealing with more specific situations.

Which method is for me?

Often it depends on various criteria: all methods have advantages and disadvantages that must be weighed.
The following factors should be considered when making a decision:

Dependencies 

For all the above methods, there are certain dependencies – be it to software providers, platforms or modules.
In general, we always try to keep dependencies to a minimum: the more dependencies or extensions a system has, the more complex it becomes, which can lead to intermediate problems during updates or further developments.

Support & stability

When integrating a module or service dependency, attempts should be made to obtain the best possible overview: How many other websites use it? Is it under continual development? Is there support from the community or vendor? Is it compatible with the version of Silverstripe CMS in use?

Control

The more you know about the integration – or perhaps have done parts of it yourself – the more control you will have and the ability to map out individual requirements. This can be a major advantage over an external solution which may offer numerous features but is still minimally customisable or extensible.

Adaptability

Can the solution be customised to individual desires, especially in terms of website design? External solutions are usually more or less flexible. However, often the interface cannot be adapted 100% to the website design.
This might not be a problem for some sites, but in other cases, it can seem like a disturbing foreign element.

Cost

How high are the set-up costs for the integration? Is it just a few clicks and some configuration or is development work also involved?
For external services: what are the on-going costs that I or my customer must consider?

Workability

Should the contents of the cookie consent solution, for example the cookie notification or cookie descriptions, etc, are editable in the backend?
Or is it sufficient to define them once (since the contents do not often change) and to save them as code/configuration?

Summary

What fits best for me and my website project?
Can I also adapt and reuse this integration for other websites?

The quick and seemingly uncomplicated path is via an external service (a so-called “cookie compliance platform”): the configuration is usually simple, as is the integration into the website.
However, adaptability, on-going costs as well as the fact that an additional external service may have to be integrated tend to argue against this option.

On the other hand, the cookie consent integration via a module requires some one-time training – how does the module work, where is what stored?
Once you have an overview of the module, this solution offers several advantages: it is adaptable, tested by the community and can be managed via the backend.

In comparison, integration using a JavaScript library offers the greatest control and flexibility and reduces dependencies to a minimum. This is contrasted by development or integration effort and the fact that data cannot be managed via the backend.
Is the website multilingual? Then you must be carefully check how an integration is possible when using this option.

I have tried all three options – and there are possibly even more.
For our projects, adaptability is always an issue. Furthermore, we always try to keep dependencies low, especially to external services. In addition, many of our websites are multilingual.

Therefore, integration via one of the Silverstripe cookie consent modules is our preferred choice.