05.10.2026 | Lothar Ferreira Neumann
Replace Tagify CDN-loaded contrib library with a local npm asset in Drupal
install_libraries_locally.sh
composer require npm-asset/yaireo--tagify:4.35.4
my_module.module
/**
* Implements hook_library_info_alter().
*
* The tagify module loads Tagify from cdnjs.cloudflare.com. Serve it from
* npm-asset/yaireo--tagify in /libraries instead, so no request reaches a
* third party and the widget keeps working behind restrictive firewalls.
*/
function my_module_library_info_alter(array &$libraries, string $extension): void {
if ($extension !== 'tagify') {
return;
}
// Assigning replaces the CDN entries. The npm package ships an unminified
// UMD build and no *.min.css; Drupal aggregates them either way.
$libraries['tagify']['js'] = [
'/libraries/yaireo--tagify/dist/tagify.js' => ['minified' => FALSE],
];
$libraries['tagify']['css']['component'] = [
'/libraries/yaireo--tagify/dist/tagify.css' => ['minified' => FALSE],
];
$libraries['tagify_polyfils']['js'] = [
'/libraries/yaireo--tagify/dist/tagify.polyfills.min.js' => ['minified' => TRUE],
];
unset($libraries['tagify']['remote'], $libraries['tagify_polyfils']['remote']);
}
A contrib module (in this example, Tagify) declares its JavaScript library with type: external, loading it from a third-party CDN such as cdnjs.cloudflare.com. However, for privacy and digital sovereignity reasons we want to reduce the amount of data potentially being exchanged with an external provider like Cloudflare.
- Composer with the npm-asset repository configured, or composer/installers plus oomphinc/composer-installers-extender for asset packages
- An affected contrib module (in this example, the Tagify module)
composer require npm-asset/yaireo--tagify:4.35.4 pulls the library from npm via the npm-asset Composer repository, placing it under /libraries where Drupal's library system expects locally vendored assets.
hook_library_info_alter() is the key mechanism that rewires the library definition without patching the contrib module. Reassigning $libraries['tagify']['js'] and ['css']['component'] replaces the CDN-hosted files with paths into /libraries/yaireo--tagify/dist/. Crucially, unset($libraries['tagify']['remote'], ...) removes the remote key – without this, Drupal still treats the library metadata as pointing to an external library, even though the file paths were changed.
Further information
Use the CDN fetcher module to automatically save external libraries in your Drupal project. This reduces the amount of externally loaded assets.
Weitere DevBits
13.11.2025 | Peter Majmesku
14.10.2026 | Lothar Ferreira Neumann
lenient.sh
# Get lenient.
composer require mglaman/composer-drupal-lenient
# Add the module to the allow list. Use escapes for the quote signs. \" ... \"
composer config --merge --json extra.drupal-lenient.allowed-list '[\"drupal/module_with_incompatible_core_version\"]'
# You can check if the merge worked, either just take a look
# into the composer.json or use this command.
composer config --merge --json extra.drupal-lenient.allowed-list
lenient_allowed_list.json
"drupal-lenient": {
"allowed-list": [
"drupal/module_with_incompatible_core_version"
]
}