Background image
10.10.2024, Kai Gertz

Integrate external content in compliance with GDPR

External content may only be loaded with the user's consent. We show what a teaser for content that is still blocked could look like.

Strictly speaking, external, embedded content (YouTube, Instagram, LinkedIn, etc.) may only be loaded and displayed after the user has given their consent, according to the GDPR. The reason for this is that the user's IP address is already transmitted during loading - which is considered personal data according to the European Commission's directive, as described here in Consent Management.

A placeholder for (still) blocked content

But how can this situation be handled sensibly? Simply omitting the content would possibly mean a significant deterioration of the content and readers could miss important contexts. Presenting users with a reference to the required consent in the consent management dialog and a link to it would be possible, but disruptive - and would unnecessarily interrupt the flow of reading.

The best solution is probably to display a placeholder that explains to users that content should actually be displayed at this point, but that consent is required:

Screenshot of a website with external embedded content that still requires the user's consent.

(Schematic representation) Placeholder for external content that the user must first agree to display. Instead of redirecting the user to the Consent Management dialog, consent can be given here directly at the touch of a button.

Such placeholders can be found from time to time on the web and can, in principle, be developed for any consent management platform that can be addressed via JavaScript API. At Tojio, we usually use Klaro for this, but in principle there are a variety of conceivable projects that can be used for this:

The button in the placeholder is then equivalent to the switch in the Consent Management dialog. The only difference is that the dialog does not have to be opened, the switch flipped and the dialog saved / closed. The updated preferences can now be saved here and the external content loaded.

With the previous approaches, the page would normally have to be reloaded and the server would have to render the embed code for the external content instead of the placeholder.

In the following sections, an approach is presented that can dispense with this reloading and offers a better user experience (UX). In addition, this approach should be generic, i.e. not tailored to a specific consent management platform.

A custom element as a "hiding place"

An idea that partly stems from the discussion on Consent Management in Drupal Starshot is to realize such a placeholder as a Custom Element (or Web Component): the Custom Element encloses and hides the actual content as long as there is no consent from the user to display it. This solution could:

  • work independently of Drupal in static websites or in conjunction with any frontend framework (React, Vue,..)
  • work with almost any consent management platform (see above)

Enclosing the external content (which itself is still in an HTML comment and is therefore inactive) has the advantage that the entire page does not have to be reloaded. Only the placeholder disappears and leaves the space for the now activated external content.

The placeholder component

The placeholder component is simply placed as a wrapper around the actual content, which is also enclosed in an HTML comment (even if it were not, the content would still remain hidden, as the component only shows the content of its shadow root to the outside world after it has been inserted, but not the child elements it has in the DOM tree).

The following must be specified for the placeholder component via attributes:

  • the service-id (as used by the Consent Management Platform),
  • name of the service,
  • description of the content to display in the preview
  • and (optionally) the aspect-ratio

Specifying the aspect ratio is technically unnecessary, but it helps to prevent shifts in the layout when the real content is loaded instead of the preview. This enables a visually smoother transition to the real content. Here in the example, the pixel values width/height are simply specified as given by the container of the real content.

<consent-required 
  service="video" 
  service-name="External video on YouTube/Vimeo" 
  content-description="What is the Drupal Starshot Initiative?" 
  aspect-ratio="903/363">
  
  <!--
    ... video embed code here ...
    ... could be anything else, too ..
  -->
      
</consent-required>

Communication between Consent Management and the component

What is still missing is the communication layer that mediates between the Consent Management Platform that is already in use and the placeholder component. If it is registered in the Consent Management Platform that the user has activated service XY, this should be passed on to all interested parties - including our placeholder component. This in turn can then swap the placeholder for the real content and all external media can be loaded.

Otherwise, if the "Load content" button is clicked in the placeholder (which should be equivalent to activating the corresponding service in the Consent Management Platform, but by the shortest route), this must be communicated to the Consent Management Platform depending on its API, whether by firing an event or a direct function call.

For both directions of communication, a helper object could be written in Javascript (a behavior in Drupal). Or - our approach here - the functionality is defined in a further component, which in turn acts as a wrapper for the placeholder component. The overall structure would then look like this:

<cmpname-consent-required>
  <consent-required 
  	service="video" 
  	service-name="External video on YouTube/Vimeo" 
  	content-description="What is the Drupal Starshot Initiative?" 
  	aspect-ratio="903/363">
  	
    <!--
    	<iframe src="https://xyz..." 
            width="640" 
            height="360" 
            loading="lazy" 
            class="media-oembed-content"
            title="What is the Drupal Starshot Initiative?">
        </iframe>
    -->
        
  </consent-required>
</cmpname-consent-required>

Using the component with Drupal and Klaro

In Drupal, the component is part of the theme. There it is defined with the usual mechanism as a library in the file theme.libraries.yml (it could also be used even more conveniently as Single Directory Component, but that is the subject of another blog article 😀 ...

consent-required:
  js:
    components/organisms/consent-required/consent-required.js: {}
    components/organisms/consent-required/adapters/klaro-consent-required.js: {}
  css:
    theme:
      components/organisms/consent-required/consent-required.css: {}

Then only the template for the "Remote Video" media type needs to be changed so that:

  • the library is activated when this template is used
  • the component is placed around the content
<div{{ attributes.addClass('media-type--' ~ media.bundle() ~ ' view-mode--' ~ view_mode ~ ' mid-' ~ media.id() ~ ' media-lang-' ~ media.field_media_document.langcode ) }}>
  {{ title_suffix.contextual_links }}
  {{ attach_library('soh/consent-required') }}
  <klaro-consent-required>
    <consent-required
      service="youtube"
      service-name="Video auf YouTube"
      aspect-ratio="770/433"
      aspect-ratio-above="625"
      content-description="Video: {{ media.label() }}"
      agree-label="{{ 'Load content from YouTube' | t }}"
      consent-required-text="{{ 'This video is hosted on YouTube. By clicking on the button below, you consent to use the YouTube service. Please note that personal data may be transmitted to YouTube. For more information, see our privacy policy.'|t }}"
    >
      <!--{{ content.field_media_oembed_video.0 }}-->
    </consent-required>
  </klaro-consent-required>
</div>

The component in productive use

The web component <consent-required> is used, for example, in the annual report of Hoffnungszeichen e.V. - it is active as long as users have not given their consent to external content from YouTube. Similarly, it is used for Google Maps on the start page of the NGO:

Screenshot of the &quot;Annual Report&quot; page of Hoffnungszeichen with a GDPR-compliant teaser for YouTube content
Screenshot of the home page of Hoffnungszeichen e.V.

The custom element is free software, as are the adapters for various consent management platforms (currently Klaro and CookiesJSR) - if anyone builds their own adapters: let us know, we'll be happy to integrate them.