Drupal core ships no cookie banner. Every consent feature is a contrib module, and in 2026 the module you'd reach for has changed. The long-running EU Cookie Compliance module is now minimally maintained, and its own project page tells you to look at Klaro, which was chosen as the consent module for the new Drupal CMS distribution.
Why the recommendation shifted to Klaro
The EU Cookie Compliance project page is blunt about its status. It's flagged minimally maintained and maintenance fixes only, and the overview states that the Klaro module was chosen for Drupal CMS because it offers more up to date features. The page even links a migrator for teams moving off it (EU Cookie Compliance on Drupal.org). The stable release still supports Drupal 8.9 through Drupal 11, so existing sites aren't stranded, but new builds shouldn't start there.
Klaro wraps the open-source Klaro! JavaScript library. You define services (Google Analytics, Matomo, an embedded YouTube player), group them by purpose, and the module blocks each service until the visitor consents. It supports onAccept and onDecline callbacks and can auto-attribute script tags for blocking (Klaro on Drupal.org).
How Klaro blocks scripts
Klaro takes the same approach a good CMP does: it neutralizes a managed script tag (switching it so the browser won't run it) and activates the service only after consent. You register each service in configuration, describe what it does, and assign it a purpose. When a visitor accepts a purpose, Klaro releases the matching services and fires their callbacks.
One Drupal-specific point: Drupal caches rendered pages aggressively. The consent decision has to stay client-side so a cached page still respects the visitor's current choice. Klaro handles this because its gate runs in the browser, not in the render layer. Test with your page cache and dynamic page cache both on, the way production runs.
Setting up a Klaro service
The workflow is straightforward once the module is in place. Install it with Composer (composer require drupal/klaro), enable it, then open Klaro's settings under the site's Configuration area. You add one service per tool: give it a machine name, a human label, a description, and assign it to a purpose like analytics or marketing. Klaro can attribute existing script tags to a service so they're blocked until that service is accepted, and its onAccept and onDecline callbacks let you run custom logic when a visitor changes their mind. Common services on a Drupal site go well beyond Google Analytics: an embedded YouTube or Vimeo player sets cookies, Google Maps sets cookies, social sharing widgets set cookies, and reCAPTCHA on a Webform contacts Google on load. Each of those is a service you register and gate, or an embed you let Klaro replace with a click-to-load placeholder.
Other Drupal options
Klaro isn't the only choice. The COOKiES module and CookieYes both have Drupal integrations, and plenty of sites embed a hosted consent platform instead of managing module configuration per site. If you run a fleet of Drupal sites, or you need cookie scanning and stored consent records across all of them, a hosted embed is often less to maintain than tuning Klaro's service list on every property.
Wiring up Consent Mode v2
If you run Google Ads or GA4 for EEA or UK visitors, you need Consent Mode v2, required since March 2024. Set the gtag consent defaults to denied before any Google tag loads, then push an update from your consent tool's accept callback (or through Google Tag Manager):
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('consent', 'default', {
ad_storage: 'denied',
analytics_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
wait_for_update: 500
});
</script>Keep a record of consent
Klaro handles the browser-side gate well, but by default it doesn't keep a server-side log of who consented, to what, and when. Article 7 of the GDPR says you have to be able to demonstrate consent, and a cookie on the visitor's machine storing their choice isn't the same as an audit trail you can produce months later if a regulator asks. If your risk profile calls for proof (a regulated sector, heavy EU traffic, a history of complaints), either add a Drupal module that logs consent events to the database or use a hosted platform that stores timestamped records for you. The proof of consent guide covers what a defensible record looks like.
Embedding a CMP instead
To use a CDN-loaded consent platform on Drupal, add the loader to the page head. You can put it in your theme's html.html.twig, add it through a module like Asset Injector, or place it in a block region that renders in the head. It has to come before your analytics and marketing tags:
<!-- Head: load the consent script FIRST, before any tag -->
<script async src="https://cdn.cookiebeam.com/banner/YOUR_BANNER_ID/default/loader.js"></script>CookieBeam then holds any tag you mark with type="text/plain" and a data-category until the visitor opts in, scans your published pages to keep the cookie policy accurate, and stores a timestamped consent record so you can demonstrate consent when asked.
Test checklist
- Load a page from a fresh EU-IP private window with caching on, and check Application › Cookies before clicking. Only strictly necessary cookies should exist.
- Reject and confirm no analytics or marketing cookies appear.
- Accept and confirm the services activate.
- Re-run an audit after adding any module that embeds third-party content.
For a broader comparison of tools and approaches, see the CMP comparison and the GDPR cookie checklist.