Adobe Commerce: Setting Up Custom Module for Cookiebot Integration
Our article gives a clear look at how the ShiftSaas Cookiebot module is set up in a Magento 2 project β both on the backend and frontend. It’s a nice clean structure that really hits the sweet spot between backend config and frontend control, especially for handling cookie consent with Cookiebot.
High-Level View Custom Module Directory

Register ShiftSaas Module
Eg: app/code/ShiftSaas/Cookiebot/registration.php
<?php
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
ComponentRegistrar::MODULE,
'ShiftSaas_Cookiebot',
__DIR__
);
Declaring Modules with Dependencies
Eg: app/code/ShiftSaas/Cookiebot/etc/module.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="ShiftSaas_Cookiebot" setup_version="1.0.0">
<sequence>
<module name="ShiftSaas_Base"/>
</sequence>
</module>
</config>
The ShiftSaas_Base module includes the system.xml configuration located at app/code/ShiftSaas/Base/etc/adminhtml/system.xml, as follows.
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<tab id="shiftsaas" translate="label" sortOrder="10">
<label>ShiftSaas</label>
</tab>
</system>
</config>
Extra Config Files
Eg: app/code/ShiftSaas/Cookiebot/etc/adminhtml/system.xml
Add-On Admin Configs When Needed

Defining Admin Controls
Eg: app/code/ShiftSaas/Cookiebot/etc/adminhtml/system.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="cookiebot" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="30">
<label>Cookiebot</label>
<tab>shiftsaas</tab>
<resource>Magento_Config::config</resource>
<group id="general" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>General</label>
<field id="enabled" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1">
<label>Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="cbid" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1">
<label>Cookiebot ID (CBID)</label>
</field>
</group>
</section>
</system>
</config>
Backend Settings Tree
app/
βββ code/
βββ ShiftSaas/
βββ Cookiebot/
βββ etc/
β βββ adminhtml/
β β βββ system.xml
β βββ module.xml
βββ registration.php
βββ Block/
β βββ CookiebotConfig.php
βββ view/
βββ frontend/
βββ layout/
βββ default.xml
βββ templates/
βββ script.phtml
Config Flag Summary
Field ID | Config Path | Type | Is Flag? |
---|---|---|---|
enabled | cookiebot/general/enabled | select (yes/no) | Yes |
cbid | cookiebot/general/cbid | text | No |
Accessing Cookiebot Settings

Serving Data from PHP to Templates

Store Config Flag Check
Using cookiebot/general/enabled from the configuration defined in system.xml.
public function isEnabled(): bool
{
return $this->scopeConfig->isSetFlag(
'cookiebot/general/enabled',
ScopeInterface::SCOPE_STORE
);
}
Expose CBID Setting
Using cookiebot/general/cbid from the configuration defined in system.xml.
public function getCookiebotCbid(): ?string
{
return $this->scopeConfig->getValue(
'cookiebot/general/cbid',
ScopeInterface::SCOPE_STORE
);
}
Template for Flexibility
Summary: Layout XML β Instantiates PHP Block Classes β PHP outputs HTML/templates
<?php
namespace ShiftSaas\Cookiebot\Block;
use Magento\Framework\View\Element\Template;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\ScopeInterface;
class CookiebotConfig extends Template
{
protected ScopeConfigInterface $scopeConfig;
public function __construct(
Template\Context $context,
ScopeConfigInterface $scopeConfig,
array $data = []
) {
parent::__construct($context, $data);
$this->scopeConfig = $scopeConfig;
}
..
}
Hook Block Head
Summary: XML (default.xml
) calls block β Block runs PHP (CookiebotConfig.php
) β PHP renders HTML (script.phtml
)
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="head.additional">
<block class="ShiftSaas\Cookiebot\Block\CookiebotConfig"
name="shiftsaas.cookiebot.script"
template="ShiftSaas_Cookiebot::script.phtml"/>
</referenceBlock>
</body>
</page>
Renders Consent Script Based on CBID

Cookiebot Script Output
<?php
/** @var \ShiftSaas\Cookiebot\Block\CookiebotConfig $block */
$cbid = $block->getCookiebotCbid();
if (!$block->isEnabled() || !$cbid) {
return;
}
?>
<script id="Cookiebot"
src="https://consent.cookiebot.com/uc.js?cbid=<?= htmlspecialchars($cbid, ENT_QUOTES, 'UTF-8') ?>"
data-culture="EN">
</script>
Connect Cookiebot Domain
Visit https://www.cookiebot.com/en/cmp-login/ to register a profile with your domain and obtain your CBID key and embed script.
Theme-Level Integration (Alternative to System-Level)
This approach is usually temporary β it’s a quick way to test configuration from the guide or embed the Cookiebot script before moving to a system-level integration where configuration is fully driven. Below is the structure we’re using for this setup:

Script Head Injection
Overriding or extending Magento’s layout XML to inject <script>
tag into the HTML <head>
section of every frontend page.
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<script src="Magento_Theme::js/cookiebot.js"/>
</head>
</page>
Frontend Cookie Loader
Just tells Magento to load JavaScript file like cookiebot.js right into the of your frontend pages.
require([
'https://consent.cookiebot.com/uc.js?cbid=<Your CBID Key>',
'domReady!'
], function () {});
Summing Up the Cookiebot Integration
We went through a theme-level setup to get Cookiebot running in Adobe Commerce β registering your domain, grabbing the CBID, and dropping the script in via default_head_blocks.xml
and a custom cookiebot.js
. Itβs a quick and simple way to test things out using your theme files (as shown in the diagram).
That said, this approach is best for quick tests or short-term use. For long-term or multi-site projects, a system-level integration (with proper modules, admin settings, and event hooks) is the way to go. It gives you more control and fits better with Magentoβs architecture.
Next up? Consider turning this into a full module with backend config and CMS tools to future-proof your setup.