GDPR Compliant User Consent Management with Klaro
Tags: gdpr, cookie, klaro, consent
Published: 2021-04-21 13:44:59

Managing user consent while complying to the latest GDPR policies can be very confusing and frustrating - but it doesn’t have to be!

We would like to show you how to get started with [Klaro](https://heyklaro.com/) - an **open-source** and **GDPR-compliant consent management tool** developed by the german company [KIProtect](https://kiprotect.com/).

If you are new to the whole GDPR and cookie consent topic, please read our article: [Best practises to build GDPR-compliant cookie banners with Klaro](https://dev.to/taikonauten/best-practises-to-build-gdpr-compliant-cookie-banners-with-klaro-nn3) 

# How to integrate Klaro GDPR-compliant consent management tool 

To get started, we will need two things: a copy of the **Klaro widget** and a valid **configuration**.

## Including the Klaro widget

To use the widget on your site, simply embed the latest release using the provided CDN. Please see the [official integration documentation](https://heyklaro.com/docs/integration/overview) to get a detailed explanation of the different options. The following snippet will get you started:

```html
<script defer 
        type="application/javascript"
        src="https://cdn.kiprotect.com/klaro/latest/klaro.js">
</script>
```

You can also [download the latest release](https://cdn.kiprotect.com/klaro/latest/klaro.js) and self-host the widget using the following example:

```html
<script defer 
        type="application/javascript" 
        src="klaro.js"> <!-- point to the downloaded file on your webserver/app -->
</script>
```

If you now reload the page, nothing will have changed yet. We are still missing the configuration.

## Node.js integration

If you are using the [node package manager](https://www.npmjs.com/), Klaro is also available as a Node.js module. Simply install it using:

```bash
npm install klaro
```

# How to configure Klaro

After you have successfully included the widget using one of the options above, you create your configuration file. Klaro uses a **central configuration object** to reference all of your services (things like Google-Analytics or YouTube videos). It will also **allow translations to be set and updated**. There are many options and you should check the [official configuration template](https://heyklaro.com/docs/integration/annotated-configuration) to see all available settings.

A sample configuration for loading **Google-Analytics** might look like this:

```javascript
var klaroConfig = {
    privacyPolicy: '/privacy.html',
    apps : [
        {
            name : 'google-analytics',
            default: true,
            title : 'Google Analytics',
            purposes : ['statistics'],
            cookies : [/^ga/i]
        }
    ]
}
```

**The configuration needs to be present in order to get the Klaro-widget to show up**. Let’s extend our previous example with our configuration:

```html
<!-- INCLUDE WIDGET -->
<script defer 
        type="application/javascript"
        src="https://cdn.kiprotect.com/klaro/latest/klaro.js">
</script>

<!-- WIDGET CONFIGURATION -->
<script>
  var klaroConfig = {
      privacyPolicy: '/privacy.html',
      apps : [
          {
              name : 'google-analytics',
              default: true,
              title : 'Google Analytics',
              purposes : ['statistics'],
              cookies : [/^ga/i]
          }
      ]
  }
</script>
```

If you now reload the page, you should be greeted by the following consent-banner:

![Consent modal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/to1jzj3ex887awtaq01i.png)

Let’s take a closer look at our configuration!

```javascript
privacyPolicy: '/privacy.html'
```

This value represents the URL or path to your privacy policy. It is mainly used inside the individual translation texts, to make references to the privacy policy.

```javascript
apps
```

An **app** is basically any service (tracking, embeds, etc.) that requires the user’s consent. Examples might be **Google-Analytics**, **Matomo**, **Instagram**, **Facebook** or **Google Maps**. This of course might also be your own cookies or services you provide.

```javascript
name : 'google-analytics',    // internal name, reference when including 3rd-party scripts
default: true,                // should the option be enabled by default?
title : 'Google Analytics',   // displayed name in modal
purposes : ['statistics'],    // group (if multiple apps of the same kind)
cookies : [/^ga/i]            // regex matcher to determine cookies
```

# How to update third-party scripts in Klaro

Now that we have the widget up and running, we need to make sure the **third-party scripts are not loaded until the user has consented** to the apps. As of right now, you might have a consent-banner but **Google will still be tracking the user** in the background and cookies might still get stored on the user’s system.

This is the default snippet used when including Google-Analytics. By default, this code would always execute once the page has been loaded.

```html
 <script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
</script>
```

First let’s **prevent the script from executing** by adding `type="text/plain"` to the script-tag.

```html
<script type="text/plain">
  // GA tracking code
</script>
```

Next, we need to add a **data-attribute** to tell Klaro what the script’s original type was, by adding `data-type="application/javascript"`

```html
<script type="text/plain"
        data-type="application/javascript">
  // GA tracking code
</script>
```

Last, we have to tell Klaro which of the previously defined apps corresponds to this script by adding the app name as the `data-name="google-analytics”` attribute. This is what you should end up seeing:

```html
<script type="text/plain"
        data-type="application/javascript"
        data-name="google-analytics">
  // Info: data-name corresponds to name in configuration file 
  // GA tracking code
</script>
```

Now the page should not be executing the Google-Analytics script until the user has consented to the tracking. That’s the basic setup done! No more tracking without the user’s consent.

# Helpful guides and snippets

Here are some common steps and configurations on how to get most out of your consent-widget:

## How to change the default texts

In order to change the default texts, you need to **define the corresponding translation** inside your configuration. You can find the **translation keys** for each language in the [official source code](https://github.com/KIProtect/klaro/tree/master/src/translations).

Let’s assume we want to update the default modal headline, text and button labels:

```javascript
var klaroConfig = {
    privacyPolicy: '/privacy.html',
    apps : [
        {
            name : 'google-analytics',
            default: true,
            title : 'Google Analytics',
            purposes : ['statistics'],
            cookies : [/^ga/i]
        }
    ],
    translations: {
    	'en': {
        	'consentModal': {
				'title': 'My new fancy title!', // update the main title
				'description': 'A detailed description of what this is.', // main description
				'privacyPolicy': {
                  'text': 'Read our {privacyPolicy} right now!' // using {brackets} we can use placeholders
                }
            },
            'acceptSelected': 'Press me!' // override accept button label
        }
    }
}
```

Using these **updated translations**, this is what the new modal should look like:

![Consent modal with custom translation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7bre413zapm8jy6jnsyp.png)

**Tip**: Customise your Klaro widget even further by overwriting the default CSS classes. 

## How to show a consent overlay on embedded content

This is a very useful feature that not many people might know about. Imagine you are using embedded content like **Facebook**, **Google Maps** or **Youtube**. Users might not want to load all of the embedded content when visiting a site and might want to allow only individual elements. Check the [official documentation](https://heyklaro.com/docs/tutorials/contextual_consent) for a detailed explanation.

Let’s assume you have an **embedded Youtube** video:

![Embedded youtube video](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fp6ifntdl7ytrnnjpz82.png)

```html
<iframe width="560" height="315" 
        src="https://www.youtube.com/embed/nXkgbmr3dRA" frameborder="0" allow="encrypted-media;" allowfullscreen>
</iframe>
```

So let’s add Klaro and create a configuration including the following options:

```javascript
var klaroConfig = {
    acceptAll: true,
    apps: [
        {
            purposes: ['marketing'],
            name: "youtube",
            contextualConsentOnly: true // this option enables inline consent
        }
    ]
}
```

We have added the `contextualConsentOnly` option. Using this configuration, we need to update our iFrame. Add the `data-name=”youtube”` attribute and update the `src=”...”` attribute by adding the `data-src=”...”` prefix.

![Blocked embedded video](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j7t30fp1m9nccz0yk5ph.png)

```html
<iframe width="560" height="315" 
        data-name="youtube"
        data-src="https://www.youtube.com/embed/nXkgbmr3dRA" frameborder="0" allow="encrypted-media;" allowfullscreen>
</iframe>
```

As you can see, the **iFrame will no longer load initially** and you can enable the external service right where it would be displayed on the page.

## How to make a reusable React component

If you plan to reuse the component in multiple projects, we recommend putting all Klaro code into a **dedicated component**.

```javascript
import React from 'react'
import '../../styles/cookies.scss' // Path to your cookie styles
import { CookieConfig } from './CookieConfig'; // Path to your config file

const Cookies = class extends React.Component {

  componentDidMount() {

    // Initialize Klaro cookie consent
    var Klaro = require('klaro');
    // we assign the Klaro module to the window, so that we can access it in JS
    window.klaro = Klaro;

    // we set up Klaro with the config
    Klaro.setup(CookieConfig);
  }

  render() {
    return (
      <></>
    )
  };
}

export default Cookies;
```

To use it, just add:

```html
<Cookies />
```

# Klaro offers scaleable, future-proof and developer friendly GDPR consent management

Having worked with different libraries and providers, Klaro has proven itself to be a **great alternative**. Any documentation is always a good indicator on the quality of the library and **Klaro’s source code has been well documented**. Klaro is **free of charge** and does **scale well** with any website or application. Together with the many **customisation options**, this consent management tool should cover most of your needs.

As always, make sure to carefully check your requirements before choosing a user consent management solution. We will be releasing an article on best practises for building GDPR-compliant cookie banners with third party tools soon. Stay tuned!