- Issue created by @ActuallyAM
- 🇪🇨Ecuador jwilson3
I agree with this issue, and so does the community, for the same reason outlined in the OP.
See https://www.drupal.org/docs/develop/creating-modules/adding-assets-css-j... →
Emphasis mine:
Inline JavaScript is highly discouraged. It is recommended to put the JS you want to use inline in a file instead, because that allows JavaScript to be aggregated and cached on the client side for performance, and enables the use of a stronger Content Security Policy to protect against XSS and other vulnerabilities.
Furthermore, the inline script is added to html_head instead of the footer, which adds a bit of unnecessary performance overhead.
Both of these points are mentioned in the Siteimprove Analytics help page:
We recommend that the JavaScript is always added at the bottom of the website in a footer or similar, just before the closing HTML body tag. Also, JavaScript can be blocked by a content security policy (CSP) configured to prevent unwanted cross-site-scripting. If you use CSP, please configure it to allow the Siteimprove script.
It seems there is no easy way to add JS to the footer from page_attachments unless you:
- Use *.libraries.yml, whereby JS files are added to the footer of the page by default. This suffers from the problem that the JS script URL is different for every site due to the unique
$config['siteimprove_analytics.settings']['code']
and therefore hard to add a dynamic URL with libraries.yml files. In theory the module could use hook_js_settings_alter() but it feels wrong to hack your own library definition. - Use hook_preprocess_html() instead of hook_page_attachments() to add the script to the page_bottom variable manually. This is probably the only practical approach this module can use.
There might be other ways but I had to set the problem down for the moment.
Additionally, since the module's functionality is so small in scope, I decided to just write my own custom module leveraging approach 1 from above.
MYMODULE.libraries.yml:
siteimprove-analytics: js: https://siteimproveanalytics.com/js/siteanalyze_11378.js: type: external attributes: async: true
MYMODULE.module
<?php /** * @file * Primary module hooks for MYMODULE module. */ /** * Implements hook_page_attachments(). */ function MYMODULE_page_attachments(array &$attachments) { // Don't add on admin pages if (\Drupal::service('router.admin_context')->isAdminRoute()) { return; } // Check if we're on an allowed domain. $allowed_domains = [ 'MYSITE.com', 'dev.MYSITE.com', 'test.MYSITE.com', 'MYSITE.ddev.site', ]; $current_domain = \Drupal::request()->getHost(); if (in_array($current_domain, $allowed_domains)) { $attachments['#attached']['library'][] = 'MYMODULE/siteimprove-analytics'; } }
MYMODULE.info.yml
name: MYMODULE description: Adds Siteimprove Analytics script to specified environments. type: module core_version_requirement: ^9 || ^10 || ^11 package: custom
- Use *.libraries.yml, whereby JS files are added to the footer of the page by default. This suffers from the problem that the JS script URL is different for every site due to the unique