Iubenda logo
Start generating

Documentation

Table of Contents

Prior Blocking of Cookies: Manual Tagging (with Practical Examples)

In short

In addition to displaying a cookie banner, you must also block cookies before consent. Manual tagging is one of the options available.

By making a small change to the code of the scripts that may install cookies, you allow our Privacy Controls and Cookie Solution to prevent their execution where consent has not yet been given.

The iubenda Privacy Controls and Cookie Solution allows for the management of all aspects of Cookie Law compliance: a cookie banner for notifying your users, a cookie policy for extended information, blocking of scripts prior to the granting of consent by the user and proofs of users’ preferences.

💡 Simplify your cookie-blocking process with auto-blocking!

Did you know that there’s a simpler option available for the prior blocking of cookies and trackers? Our auto-blocking feature automates the process, saving you time and effort.

If you prefer to manually tag your scripts that install or may install cookies, you can still follow the guide below for step-by-step instructions and practical examples. However, we highly recommend considering the auto-blocking feature for a more streamlined approach.

👉 Click here to learn more about auto-blocking and how it can simplify your cookie-blocking process

How to install the iubenda Privacy Controls and Cookie Solution

For an installation guide, please see our introduction to the Privacy Controls and Cookie Solution. For WordPress, please read our dedicated post for WordPress that teaches you how to use the iubenda Privacy Controls and Cookie Solution plugin for WordPress to automate the blocking of scripts.

Which cookie-installing scripts should be blocked?

This depends on the legal jurisdiction applicable to your site. In Europe, you’re legally required to block cookie scripts until user consent is obtained. All cookies must be blocked, however, there are exemptions, the so-called strictly necessary cookies.

In the case of Italy, the category of exempt cookies are:

  • Technical cookies, preference, session and optimization cookies;
  • Statistical cookies run by first-party solutions (eg. Matomo/Piwik or other solutions hosted/run by you);
  • Statistical cookies by third parties (eg. Google Analytics), but only where the data is anonymized and is not used for profiling (even indirectly).

Regarding Google Analytics

In Italy, the condition for Google Analytics to be eligible for “no prior consent necessary” is IP anonymization – however in France, Google Analytics doesn’t seem to be eligible for exceptions, and while they recommend using Matomo/Piwik – it is the anonymization of the user’s IP that allows for analysis to be carried out in a disaggregated fashion.

Google Consent Mode

To help advertisers manage cookies for analytics and advertising purposes, Google has introduced Consent Mode, a feature that allows you to avoid prior blocking for Google Analytics and Google Ads (including Google Ads Conversion Tracking and Remarketing).

Learn how to implement it with our Privacy Controls and Cookie Solution.

It’s important to note that where the GDPR applies, intended use factors into whether or not consent is required as even statistical data can fall under “profiling” or “monitoring” depending on how the data is being used.

To proceed:

  • Google Analytics: follow the guide for the anonymization of Google Analytics IP (just add an additional line to its configuration definition);
  • According to the information we have, Webtrekk and many other analytics tools are already up to standards and do not require further configuration.

Regarding other tools that guarantee the non-usage of cookies

If other third-party tools guarantee not to use cookies, perhaps by providing specific configuration options, they too can be considered to be exempt from prior blocking.

This is the case namely with YouTube, which provides a specific feature to prevent the user from being tracked through cookies.

Using Google Tag Manager to dramatically simplify the application of cookie regulations

Google Tag Manager is a free tool that helps to simplify the application of cookie regulations. It’s compatible with the iubenda Privacy Controls and Cookie Solution. You can consult our Google Tag Manager guide here.

Google Tag Manager allows you to avoid tagging scripts as described below, although this is limited to a certain category of scripts – scripts that are not positional/do not define a position. It, therefore, does not handle embed scripts such as those related to advertising banners, youtube video widgets, facebook like buttons etc. Although this method is not a cure-all, we strongly recommend that you use it.

How to implement script blocking for those scripts that may install cookies

Modifications to script

For all other scripts that install or may install cookies, you need to proceed with changes to the code to implement the blocking capability.

To enable blocking of scripts that may install cookies, you must change these scripts so that the iubenda Privacy Controls and Cookie Solution can prevent their execution where consent has not yet been given.

To do this:

  1. apply the class _iub_cs_activate to the script tags, and
  2. change the type attribute from text/javascript to text/plain
<script class="_iub_cs_activate" type="text/plain" src="code-source.js">
….
</script>

The src can remain unchanged, but it is advisable to replace it with data-suppressedsrc or with suppressedsrc. Replacing src is in some cases necessary, as the browser, even though the script is blocked, may download and/or interpret the resource and consequently install cookies.

// use of data-suppressedsrc
<script data-suppressedsrc="LINK-TO-SOURCE.js" class="_iub_cs_activate" type="text/plain">

</script>


// OR suppressedsrc
<script suppressedsrc="LINK-TO-SOURCE.js" class="_iub_cs_activate"  type="text/plain">

</script>

Note: for script re-activation, the iubenda Privacy Controls and Cookie Solution handles src re-activation by controlling the previously described attributes in the following order: data-suppressedsrc, suppressedsrc and src (if it is left unchanged).

To activate the Javascript inline tag, you must instead apply the class _iub_cs_activate-inline.

<script class="_iub_cs_activate-inline" type="text/plain">
….
</script>

Note: The class _iub_cs_activate-inline should only be used in place of _iub_cs_activate if the blocked script uses document.write and/or document.writeln, regardless of whether the script is inline or an external resource.

JavaScript modules

Thanks to the custom attributes suppressedtype and data-iub-type, our Privacy Controls and Cookie Solution can also block/activate scripts other than text/javascript (e.g. module):

<script type="module">
   console.log('this is a module, e.g. "this" is undefined:', this);
</script>

To block it:

<script suppressedtype="module" type="text/plain" class="_iub_cs_activate">
   console.log('this is a module, e.g. "this" is undefined:', this);
</script>

or (equivalent alternative):

<script data-iub-type="module" type="text/plain" class="_iub_cs_activate">
   console.log('this is a module, e.g. "this" is undefined:', this);
</script>

If you’ve enabled the per-category consent feature you’ll need to specify the categories of the scripts/iframes with a special comma-separated data-iub-purposes attribute, e.g. data-iub-purposes="2" or data-iub-purposes="2, 3" (it’s rare, but a single activator can serve different purposes).

We remind you that the purposes are grouped into 5 categories (Necessary, Functionality, Experience, Measurement, Marketing), each having an id (1, 2, 3, 4, 5):

  1. Necessary (id 1). Purposes included:
    • Backup saving and management
    • Hosting and backend infrastructure
    • Managing landing and invitation pages
    • Platform services and hosting
    • SPAM protection
    • Traffic optimization and distribution
    • Infrastructure monitoring
    • Handling payments
    • Registration and authentication provided directly by @{this_application}
    • Collection of privacy-related preferences
    • Building and running @{this_application}
  2. Functionality (id 2). Purposes included:
    • Contacting the User
    • Interaction with live chat platforms
    • Managing web conferencing and online telephony
    • Managing support and contact requests
    • Interaction with support and feedback platforms
    • Tag Management
    • Registration and authentication
    • User database management
    • Connecting data
    • Handling activities related to productivity
    • Selling goods and services online
  3. Experience (id 3). Purposes included:
    • Content commenting
    • Interaction with data collection platforms and other third-parties
    • Displaying content from external platforms
    • Interaction with external social networks and platforms
    • Interaction with online survey platforms
    • RSS feed management
    • Social features
    • Access to third-party accounts
    • Tools for social media
  4. Measurement (id 4). Purposes included:
    • Analytics
    • Beta testing
    • Content performance and feature testing (A/B testing)
    • Heat mapping and session recording
    • Managing data collection and online surveys
  5. Marketing (id 5). Purposes included:
    • Advertising
    • Advertising service infrastructure
    • Commercial affiliation
    • Managing contacts and sending messages
    • Remarketing and behavioral targeting

Let’s take the Twitter follow button for example:

<a href="https://twitter.com/iubenda" class="twitter-follow-button" data-show-count="false">Follow @iubenda</a>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Since the Twitter follow button is part of the “Interaction with external social networks and platforms” purpose included in the “Experience” category (3), the code will become:

<a href="https://twitter.com/iubenda" class="twitter-follow-button" data-show-count="false">Follow @iubenda</a>
<script async type="text/plain" class="_iub_cs_activate" data-iub-purposes="3" data-suppressedsrc="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

With the exception of strictly necessary cookies (which don’t need consent), you must add the data-iub-purposes attribute to all your scripts if you use per-category consent so that the Privacy Controls and Cookie Solution can properly identify the scripts for release. When the per-category feature is enabled scripts/iframes without the data-iub-purposes attribute or with at least one purpose rejected will remain blocked, so please be sure to add it in each instance.

Callback

Alternatively, in the case where cookies are activated by portions of Javascript code, it’s possible to proceed via callback to the instance csConfiguration.

// onConsentGiven is still active but deprecated: if both are declarated only onConsentRead will be executed.
_iub.csConfiguration = {
  callback: {
    onConsentRead: function(){ yourFunctionForRegisterCookie() ;}
  }
}

Note: onConsentGiven, specified above, is still available for compatibility reasons with earlier versions; its value will in any case be overridden by onConsentRead if the latter is used.

Modifications of scripts, iframe and img for dependency management

In some cases, in order to properly re-activate a blocked tag it is necessary to wait for the availability of a variable or a javascript object. To properly manage dependencies you’ll find the data-iub-cs-wait-for attribute.

<script suppressedsrc="//download.helloworldvariable.js" class="_iub_cs_activate">
</script>

<script data-iub-cs-wait-for="helloWord" class="_iub_cs_activate-inline">
  console.log('print hello world' + helloWorld);
</script>

img and iframe tags

Various img and iframe tags could install cookies as well. In these cases it’s necessary to add the class _iub_cs_activate (just like for the script tags described above), assign the original value of the src tag to a new attribute called data-suppressedsrc or suppressedsrc and assign the value "about:blank" to src (see the example below to visualize these rules).

<iframe id="player" class="_iub_cs_activate" width="640" height="390" frameborder="0" suppressedsrc="https://www.youtube.com/embed/erVv_Gm7CC4" src="about:blank"></iframe>

Note: the value data:text/html;base64,PGh0bWw+PGJvZHk+U3VwcHJlc3NlZDwvYm9keT48L2h0bWw+ previously indicated in this guide (it’s the codified base64 version of: Suppressed, which will then be shown by most browsers before the consent instead of the actual output of the script) does not affect the correct blocking and the subsequent activation of the tag, but its use may result in errors in displaying some Android web views.

At this address you’ll find a code/encode tool in order to generate any other base64 version of any other string.

noscript tags

At present the noscript tag that may install cookies in cases in which the user has disabled JavaScript in his browser, is in an implementation phase. In order to be prepared for these cases as well we suggest to eliminate noscript tags from the document or to use backend solutions instead, that could after discovering the presence of the cookie _iub_cs-local, selectively include or exclude the noscript tags from the documents.

Practical examples

Below are examples of commonly used scripts and guidance on how to modify them as to comply with cookie law.

4w Marketing

Before

After:

1. define the callBack for onConsentGiven on the instance _iub.csConfiguration

onConsentGiven: function () { 
$('.4wNET.hidden').removeClass('hidden');
}

2. include the entire script that loads the banner in a div with “display:none” set – Example


AddThis

Button:


AddToAny


AdRoll


Altervista

Altervista and his ad providers join and support the Transparency and Consent Framework. More info on the Altervista Wiki.


Amazon

Banner

Login


Bing Tracker


Booking (affiliate)


CodePen


Criteo

  • Before
  • After – The URL resource is first built entirely into the block code and then inserted into the src property of the script tag.

Customerly


Disqus


Elevio


Facebook

Pixel

Like button

Like box

Page plugin


Foursquare


Freshchat


Note: snippets must be blocked in a specific order if there are more Ads Conversion per page

  • The first snippet must be blocked with the _iub_cs_activate-inline class
  • All subsequent snippets must be blocked with the _iub_cs_activate class

In doing so, the first conversion snippet will be:

<script class="_iub_cs_activate-inline" type="text/plain">
        /* <![CDATA[ */
        var google_conversion_id =CONVERSION_ID;
        var google_conversion_label = "CONVERSION-LABEL";
        var google_custom_params = window.google_tag_params;
        var google_remarketing_only = true;
        /* ]]> */
</script>
<script class="_iub_cs_activate-inline" type="text/plain" src="//www.googleadservices.com/pagead/conversion.js">
</script>
<noscript>
    <div style="display:inline;">
        <img height="1" width="1" style="border-style:none;" alt="" class="_iub_cs_activate" src="data:text/html;base64,PGh0bWw+PGJvZHk+U3VwcHJlc3NlZDwvYm9keT48L2h0bWw+" suppressedsrc="//googleads.g.doubleclick.net/pagead/viewthroughconversion/1036022355/?value=0&amp;label=-KpbCO3v1QQQ0-SB7gM&amp;guid=ON&amp;script=0"/>
    </div>
</noscript>

While the subsequent conversion snippets will become:

<script class="_iub_cs_activate" type="text/plain">
        /* <![CDATA[ */
        var google_conversion_id =CONVERSION_ID;
        var google_conversion_label = "CONVERSION-LABEL";
        var google_custom_params = window.google_tag_params;
        var google_remarketing_only = true;
        /* ]]> */
</script>
<script class="_iub_cs_activate" type="text/plain" src="//www.googleadservices.com/pagead/conversion.js">
</script>
<noscript>
    <div style="display:inline;">
        <img height="1" width="1" style="border-style:none;" alt=""  type="text/plain" class="_iub_cs_activate" src="data:text/html;base64,PGh0bWw+PGJvZHk+U3VwcHJlc3NlZDwvYm9keT48L2h0bWw+" suppressedsrc="//googleads.g.doubleclick.net/pagead/viewthroughconversion/1036022355/?value=0&amp;label=-KpbCO3v1QQQ0-SB7gM&amp;guid=ON&amp;script=0"/>
    </div>
</noscript>

All the snippets on the page can be blocked with the _iub_cs_activate class. Example:

<script class="_iub_cs_activate" type="text/plain">
        /* <![CDATA[ */
        var google_conversion_id =CONVERSION_ID;
        var google_conversion_label = "CONVERSION-LABEL";
        var google_custom_params = window.google_tag_params;
        var google_remarketing_only = true;
        /* ]]> */
</script>
<script class="_iub_cs_activate" type="text/plain" src="//www.googleadservices.com/pagead/conversion.js">
</script>
<noscript>
    <div style="display:inline;">
        <img height="1" width="1" style="border-style:none;" alt=""  type="text/plain" class="_iub_cs_activate" src="data:text/html;base64,PGh0bWw+PGJvZHk+U3VwcHJlc3NlZDwvYm9keT48L2h0bWw+" suppressedsrc="//googleads.g.doubleclick.net/pagead/viewthroughconversion/1036022355/?value=0&amp;label=-KpbCO3v1QQQ0-SB7gM&amp;guid=ON&amp;script=0"/>
    </div>
</noscript>

Google AdSense


Google Analytics

The following is only implemented when using the features of Google Analytics that allow for the tracking of a unique user. In all other cases it is suggested to anonymize the IP.

gtag.js


Google Calendar


Google Maps (iframe)



Google Publisher Tag

Please note: if you run personalized ads using Google services, you’re required to ensure that explicit consent to ad personalization is collected before displaying personalized ads for end-users based in the EAA. More info here.


Google Track (with img tag)


Headway


Intercom


Kissmetrics


MediaMond


Mixpanel


MyLiveChat


OpenX banner

Note: if there are many OpenX banners on the page, you can speed up the activation using the inlineDelay option (for more information, see the iubenda Installation and Customization guide). We recommend to avoid values less than 200 milliseconds.


Optimizely


PayPal (Buy Now button)


ShareThis


Smart Adserver

Note: use asynchronous (AJAX) tags.

head

body


SoundCloud


Spotify

Listen

Follow


Stripe


TradeTracker


TripAdvisor

When Per Purpose Consent is Disabled

Badge, Read Review, and Write Review Widgets

Before:

<div id="DIV-ID" class="CLASS-DIV">
  <ul id="UL-ID" class="CLASS-UL">
    <li id="LI-ID" class="CLASS-LI">
      <a target="_blank" href="http://www.tripadvisor.co.uk/"><img src="http://www.tripadvisor.co.uk/img/cdsi/partner/tripadvisor_logo_DIMENSIONS.png" alt="TripAdvisor"/></a>
    </li>
  </ul>
</div>
<script src="http://www.jscache.com/wejs?wtype=TYPE&amp;uniq=UNIQ&amp;locationId=LocationId&amp;icon=knifeAndFork&amp;lang=en_UK&amp;display_version=2"></script>

After:

1. Add to the basic configuration of the iubenda script the reloadOnConsent as displayed below:

<script>
  _iub.csConfiguration ? _iub.csConfiguration : _iub.csConfiguration = {}
  _iub.csConfiguration.reloadOnConsent = true;
</script>

//insert it into <head> tag after iubenda configuration

2. Define isConsentGiven in order to control the cookies:

<script type='text/javascript'>
      function isConsentGiven() {
          if('consentIsGiven' in window && (consentIsGiven === true || consentIsGiven === false)) return consentIsGiven;
          if(!('_iub' in window && 'csConfiguration' in _iub)) return false;
          var siteId = _iub.csConfiguration.siteId || '';
          var cookiePolicyId = _iub.csConfiguration.cookiePolicyId || '';
          var cs = document.cookie.split(';');
          var consentIsGiven = false;
          for (var i = 0; i < cs.length; i++) {
              while (cs[i].charAt(0) == ' ') cs[i] = cs[i].substring(1);
              if(cs[i].indexOf('_iub_cs-s'+ siteId) == 0||cs[i].indexOf('_iub_cs-'+ cookiePolicyId) == 0) {
                  consentIsGiven = true;
                  break;
              }
          }
          window.consentIsGiven = consentIsGiven;
          return consentIsGiven;
      }
    </script>

3. Replace the original TripAdvisor element with the following resources, as indicated:

For the Badge Widget or Read Review Widget:

<script>
      if(isConsentGiven()){ //per ogni elemento di TripAdvisor
        document.write('<div id="DIV-ID" class="CLASS-DIV"><ul id="UL-ID" class="CLASS-UL"><li id="LI-ID" class="CLASS-LI"><a target="_blank" href="http://www.tripadvisor.co.uk/"><img src="http://www.tripadvisor.co.uk/img/cdsi/partner/tripadvisor_logo_DIMENSIONS.png" alt="TripAdvisor"\/><\/a><\/li><\/ul><\/div>');
        document.write('<script src="http://www.jscache.com/wejs?wtype=TYPE&amp;uniq=UNIQ&amp;locationId=LocationId&amp;icon=knifeAndFork&amp;lang=en_UK&amp;display_version=2"><\/script>');
      }
    </script>
<script>
      if(isConsentGiven()){ //per ogni elemento di TripAdvisor
        document.write('<div id="DIV-ID" class="CLASS-DIV"><ul id="UL-ID" class="CLASS-UL"><li id="LI-ID" class="CLASS-LI"><a target="_blank" href="http://www.tripadvisor.co.uk/"><img src="http://www.tripadvisor.co.uk/img/cdsi/partner/tripadvisor_logo_DIMENSIONS.png" alt="TripAdvisor"\/><\/a><\/li><\/ul><\/div>');
        document.write('<script src="http://www.jscache.com/wejs?wtype=TYPE&amp;uniq=UNIQ&amp;locationId=LocationId&amp;icon=knifeAndFork&amp;lang=en_UK&amp;display_version=2"><\/script>');
      }
    </script>

For the Write Review Widget:

(Consider that for this widget, additional changes include using a suppressed image source and a specific script URL for TripAdvisor.)

<script>
      if(isConsentGiven()){
        document.write('<div id="DIV-ID" class="CLASS-DIV"><ul id="UL-ID" class="CLASS-UL"><li id="LI-ID" class="CLASS-LI"><a target="_blank" href="http://www.tripadvisor.co.uk/"><img class="_iub_cs_activate" src="data:text/html;base64,PGh0bWw+PGJvZHk+U3VwcHJlc3NlZDwvYm9keT48L2h0bWw+" suppressedsrc="http://www.tripadvisor.co.uk/img/cdsi/img2/branding/150_logo-11900-2.png" alt="TripAdvisor"\/><\/a><\/li><\/ul><\/div>');
            document.write('<script src="http://www.jscache.com/wejs?wtype=cdswritereviewlg&amp;uniq=YOUR-UNIQ&amp;locationId=YOUR-LOCATION&amp;lang=en_UK&amp;border=false&amp;langversion=2"><\/script>');
        }
    </script>

When Per Purpose Consent is Enabled

Badge, Read Review, and Write Review Widgets

Before:

<div id="DIV-ID" class="CLASS-DIV">
  <ul id="UL-ID" class="CLASS-UL">
    <li id="LI-ID" class="CLASS-LI">
      <a target="_blank" href="http://www.tripadvisor.co.uk/"><img src="http://www.tripadvisor.co.uk/img/cdsi/partner/tripadvisor_logo_DIMENSIONS.png" alt="TripAdvisor"/></a>
    </li>
  </ul>
</div>
<script src="http://www.jscache.com/wejs?wtype=TYPE&amp;uniq=UNIQ&amp;locationId=LocationId&amp;icon=knifeAndFork&amp;lang=en_UK&amp;display_version=2"></script>

After:

1. Add to the basic configuration of the iubenda script the reloadOnConsent as displayed below:

<script>
  _iub.csConfiguration ? _iub.csConfiguration : _iub.csConfiguration = {}
  _iub.csConfiguration.reloadOnConsent = true;
</script>


//insert it into <head> tag after iubenda configuration

2. Define isConsentGivenByPurpose function in order to check whether consent has been given for specific purposes based on cookies.

<script type='text/javascript'>
function isConsentGivenByPurpose() {
  if('consentIsGiven' in window && (consentIsGiven === true || consentIsGiven === false)) return consentIsGiven;
  if(!('_iub' in window && 'csConfiguration' in _iub)) return false;
  var siteId = _iub.csConfiguration.siteId || '';
  var cookiePolicyId = _iub.csConfiguration.cookiePolicyId || '';
  var cs = document.cookie.split(';');
  var consentIsGiven = false;
  for (var i = 0; i < cs.length; i++) {
      while (cs[i].charAt(0) == ' ') cs[i] = cs[i].substring(1);
      var siteCookiePattern = new RegExp('^_iub_cs-s' + siteId + '=', 'i');
      var policyCookiePattern = new RegExp('^_iub_cs-' + cookiePolicyId + '=', 'i');
      if(siteCookiePattern.test(cs[i]) || policyCookiePattern.test(cs[i])) {
        try {
          var cookieContent = cs[i].split('=');
          var cookieValue = JSON.parse(decodeURIComponent(cookieContent[1]));

          var checkPurposes = true;

          for (var a = 0; a < arguments.length; a++) {
            var purposeItem = cookieValue.purposes[arguments[a]];
            if (checkPurposes && !purposeItem) {
              checkPurposes = !!purposeItem;
            }
          }

          consentIsGiven = checkPurposes
        } catch (e) {
          consentIsGiven = true;
        }
        break;
      }
  }
  window.consentIsGiven = consentIsGiven;
  return consentIsGiven;
}
</script>

3. For the Badge Widget, Read Review Widget or Write Review Widget, replace the original TripAdvisor element with the following resource:

(Consider that, for the Badge Widget and Review Badge Widget, it’s necessary to pass the appropriate purpose identifier (e.g., 2) to the isConsentGivenByPurpose function.)

<script>
if(isConsentGivenByPurpose(2)){
document.write('<div id="DIV-ID" class="CLASS-DIV"><ul id="UL-ID" class="CLASS-UL"><li id="LI-ID" class="CLASS-LI"><a target="_blank" href="http://www.tripadvisor.co.uk/"><img src="http://www.tripadvisor.co.uk/img/cdsi/partner/tripadvisor_logo_DIMENSIONS.png" alt="TripAdvisor"\/><\/a><\/li><\/ul><\/div>');
document.write('<script src="http://www.jscache.com/wejs?wtype=TYPE&amp;uniq=UNIQ&amp;locationId=LocationId&amp;icon=knifeAndFork&amp;lang=en_UK&amp;display_version=2"><\/script>');
};
}
</script>

Twitter

Follow Button

Share Button

Embedded Tweet


UserVoice


Vimeo


Viralize


YouTube

The following applies only in cases where you do not use the option that lets you include YouTube videos without installing cookies to visitors of the site.

See also