Drupal Integration
Last updated: October 5, 2026
Use the CYBEXO CMP module to load your consent banner through Drupal’s normal page rendering and connect visitor choices to Google Consent Mode v2.
Version 1.0.0 is available from the official CYBEXO CMP project. It is a separate project from the earlier Drupal integration.
Before you start
Section titled “Before you start”- Use a supported Drupal installation and PHP version. This release targets Drupal 10.6 or Drupal 11.3 and later within those major versions. Drupal 11 requires PHP 8.3 or later; follow the requirements for your installed core version.
- Create and publish a Web App for your real site domain in the CYBEXO dashboard. Copy its actual CYB App ID:
CYB-followed by ten lowercase letters or digits. - Keep the App’s Consent Mode enabled when CYBEXO will publish visitor choices to Google.
- Use one CMP installation and one Google consent owner per page. Remove duplicate manual or GTM CMP loaders when switching to the module. Retain your intended Analytics integration, with any separate consent-default writer disabled.
- Back up your site and export existing module configuration before changing installations.
Migrate legacy Apps before switching. Obtain a supported migration that preserves ownership, configuration and consent/report history, then copy the actual new CYB App ID from the dashboard. Do not change an ID prefix yourself. Creating a separate new App does not migrate the old App’s history or saved visitor choices. Contact CYBEXO support before switching if migration is unavailable.
The new package is drupal/cybexo_cmp, with machine name cybexo_cmp. It is not an in-place update of the earlier Drupal project. Do not rename module directories, namespaces or configuration keys by hand. A new module installation alone does not migrate old settings or App history.
Moving from the earlier integration
Section titled “Moving from the earlier integration”The legacy 1.0.4 module cannot start on the tested Drupal 11.4.8 installation because its controller conflicts with Drupal core. Installing the new module alongside it cannot repair that earlier failure. Do not leave the old module active when moving to that core version.
While the old site still works, retain a database backup and configuration export, then uninstall the legacy module through Drupal and remove its code before changing core. Normal uninstall removes that module’s active configuration; keep the backup and export. Install CYBEXO, enter the actual CYB App ID after any required App migration, and use the retained export to reapply the non-identity delivery options you need. If the site already cannot start, restore a reviewed working backup before performing the ordinary uninstall. Do not attempt a blind code-only removal from an active installation.
The optional Import legacy settings action appears only when a legacy configuration record is already present and the new App ID is blank. It copies recognized settings without changing the old record or unrelated new settings. It does not upload a configuration export, and ordinary uninstall is not claimed to leave an importable record. An imported retired ID remains inactive until you supply the real CYB App ID. Retained endpoint, debug and Consent Mode flags do not override current delivery or dashboard policy.
On a core where the old module can start, the new module includes safeguards against the known 1.0.4 loader and demonstration-page duplicates. Coexistence checks covered Drupal 10.6.18 with the new module enabled first. That result does not establish a working old-first migration, repair the Drupal 11.4.8 failure, or cover custom integrations. Keep one active consent owner and verify the actual installation; do not use co-installation as a general migration shortcut.
1. Install and configure
Section titled “1. Install and configure”For a Composer-managed site:
composer require 'drupal/cybexo_cmp:^1.0'drush en cybexo_cmpdrush updbdrush crYou can also use the official archive with your site’s established Drupal module workflow. Preserve its layout and use only one copy of the module. Enable CYBEXO CMP under Extend, then open its configuration page from that module’s Configure link.
Enter the dashboard-issued CYB App ID and keep automatic injection enabled for the normal installation. Review anonymous-only and admin-page exclusions for your intended audience. Admin-page exclusion also covers access-denied or missing pages under /admin; an ordinary public error page is not automatically excluded. Save, clear relevant Drupal/CDN caches and open an ordinary public page in a fresh, logged-out browser context.
The module loads https://cmp.cybexo.com/loader.js with its release query and obtains configuration and vendor-list assets from https://edge.cybexo.com. Preserve the loader URL generated by the module: removing its query can reuse an older cached runtime. The query separates that cache entry; it does not permanently pin the shared runtime version. It uses the normal CYBEXO consent/reporting service. This guide pairs module 1.0.0 with shared Web CMP 1.5.32; module and runtime versions are separate.
A correctly formatted ID alone does not establish an active App, allowed domain, entitlement or published configuration. Verify those dashboard settings if configuration delivery fails.
2. Keep consent startup before dependent tags
Section titled “2. Keep consent startup before dependent tags”The active module places the early TCF API, Google integration identifier and four denied Google defaults in the document head before normal dependent tags. This startup remains present when automatic injection is disabled, the ID is invalid, or a visitor/page is excluded; those settings control the asynchronous CMP loader. They do not grant consent.
The early API queues TCF requests until the runtime can take over. The module owns the initial ad_storage, analytics_storage, ad_user_data and ad_personalization defaults; the shared runtime publishes configured, saved and changed choices. The initial 500 ms wait accommodates asynchronous restoration, but timeout or successful script download does not establish CMP readiness.
The App’s dashboard configuration controls later Consent Mode updates. Do not rely on retained legacy module flags or endpoint overrides to change that policy. Keep the App’s Consent Mode setting enabled for Google updates.
Consent Mode is not a general third-party blocking switch. A Basic Google setup that blocks tags until consent requires its own verified blocking configuration; Advanced Mode can send cookieless requests under denial. This module does not create a universal permission API for other Drupal modules or map every vendor to a service.
Do not add another TCF bootstrap or Google consent-default snippet to this normal installation. Exclude the early consent scripts from optimizers that delay, combine or move them after Google/TCF consumers. Verify actual output order after theme, tag-manager or optimization changes.
3. Caching, BigPipe and navigation
Section titled “3. Caching, BigPipe and navigation”Use normal Drupal caching and asset aggregation. The module associates its output with configuration and visitor/route cache dependencies, so changing an injection setting can invalidate affected output. Browser consent is resolved by the runtime, not stored as a visitor-specific grant inside shared cached HTML.
Clear relevant caches after installation or updates. Test a first page load, a warm-cache reload and another route. Check logged-in visitors and administrative pages separately when exclusions are enabled. A configuration screen showing the new value does not prove every cached page has refreshed.
BigPipe and AJAX can add content after the initial page response. Early defaults and the TCF API belong in the initial head; later behavior attachment must not create another consent owner or loader. Recheck dynamically added privacy controls when your site replaces content without a full navigation.
4. Provide privacy settings access
Section titled “4. Provide privacy settings access”Add the CYBEXO privacy settings block through Structure → Block layout in a region visible on pages where the CMP is available. You can also use a button in an appropriate theme or trusted content component:
<button type="button" data-cybexo-open-privacy>Privacy settings</button>The control reopens the real CMP after accepting or rejecting so visitors can review and change their choices. Opening it does not grant consent. It uses the existing runtime and does not override automatic-injection or visitor/page exclusions.
If the runtime API is unavailable, the control displays a status message asking the visitor to reload and try again. It does not retry the loader or change consent, and the message clears after settings open successfully. The local control handler remains available on excluded pages so custom controls can give this feedback; the supplied block is empty when loading is ineligible.
Verify the control on ordinary pages and after the AJAX/BigPipe updates used by your site. If the loader is disabled, excluded or cannot load configuration, fix that condition. A link or block alone is not proof that the CMP can reopen.
5. Verify the real installation
Section titled “5. Verify the real installation”Use the public site and the exact module version you plan to release:
- Confirm one CMP loader and successful configuration/vendor-list delivery for the correct App/domain. Inspect the runtime version separately from the module version.
- In Tag Assistant, confirm the four denied defaults precede Google initialization and the expected developer ID is present. Inspect a processed event after each choice change.
- Accept All and reload. Check TCF data, Google signals and saved-decision restoration. Confirm an intended test event reaches the correct Analytics property.
- Refuse advertising personalization while retaining Analytics, then withdraw Analytics separately. Save and reload each choice; check the independent results.
- Reopen Privacy settings, Reject All, reload and reopen again. Confirm rejection is preserved and the intended tags respect withdrawal. Judge requests according to the site’s actual Basic or Advanced setup.
- Check blocked loader, configuration and vendor-list delivery, then restore delivery and reload. The page must not present a grant or readiness it has not established.
- Repeat relevant checks with warm caches, on another route and for the visitor types covered by the configuration. Test privacy controls with a keyboard, on a narrow viewport and at increased browser zoom.
A not-yet-initialized TCF API can report stub while configuration is unavailable. An initialized runtime’s vendor-list error is a different state. Do not equate a loader’s load event with a ready API, banner or saved choice.
Check normal consent/reporting records in the dashboard where enabled. A browser request, a local API result and a stored server record are separate checks. Pulse can supplement diagnostics, but a scan does not replace visitor tests or prove certification.
6. Update and recover
Section titled “6. Update and recover”For later updates within the CYBEXO module, install the official update, run Drupal database updates and rebuild caches. Repeat affected checks. Do not copy default configuration over the site’s active settings. Moving from a different module remains a migration, not a normal package update.
The Restore delivery defaults action enables automatic injection, disables anonymous-only loading and enables admin-page exclusion. It does not reset your App ID, browser consent or cloud history. Keep an export of your configuration before changing or removing the module.
Retain a compatible known-good package and settings backup. An older integration may not support your current CYB App ID, so verify compatibility before using it for recovery. Restoring module code does not undo dashboard/shared-runtime changes; restoring an old database can overwrite newer content or records.
Removing CYBEXO while a functioning legacy module remains enabled can reactivate the old loader and demonstration pages. That is not a consent-safe rollback. Restore a reviewed site/configuration backup or keep competing delivery disabled.
Uninstalling a Drupal module can remove its module-owned configuration. It is not a browser-consent reset or a cloud history deletion request. Preserve settings first and use the appropriate account/data-management process for broader deletion.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Check and fix |
|---|---|
| Invalid or retired App warning | Copy the actual CYB App ID after supported migration; do not edit an old prefix. |
| Banner is absent | Check configuration, domain, entitlement, saved choice, regional policy, injection/exclusions and delivery errors. |
| Old behavior remains after Save | Rebuild relevant caches; inspect anonymous, logged-in and admin page output. |
| Choices do not reach Google | Enable the App’s Consent Mode policy, remove conflicting consent writers and inspect Tag Assistant updates. |
| Startup is late or duplicated | Remove duplicate integrations and prevent delayed early consent; inspect aggregated/warm-cache order. |
| Privacy control asks you to reload | Check loader eligibility and configuration delivery, restore availability, then reload and try again. |
| Custom privacy control gives no response | Check the control attribute, the module’s local script and JavaScript errors. |
| Analytics event is absent | Check tag placement, consent, visitor exclusions and the intended measurement property. |