0

I am trying to disable all the JavaScript on all the pages of a Drupal 8 site for anonymous users if there is a particular header in the request object.

I tried out this code.

/**
 * Implements hook_js_alter().
 */
function MODULE_js_alter(&$javascript, AttachedAssetsInterface $assets) {
  if (MODULE_get_headers()) {
    unset($javascript);
  }
}
/**
 * Implements hook_page_attachments_alter().
 */
function MODULE_page_attachments_alter(&$attachments) {
  // This is for disabling all 3rd party libraries. 
  if (MODULE_get_headers()) {
    $attachments['#attached']['library'] = [];
  }
}

It does seem to work to a certain extent. It disables most of JavaScript, but I am seeing the styles are also off (which might be expected) as the CSS libraries might also be removed.

Is there a better way to do this? Maybe Drupal has an option to turn off all the JavaScript.

3
  • 1
    Aggregation and caching mean your code will not run for every request
    – Clive
    May 25 at 8:45
  • How do we override that? @Clive
    – Binny
    May 25 at 10:37
  • 1
    Literally? Turn off caching and aggregation. But beware, the cure may be better than the disease. I don't know enough about what you're doing to give real advice, but my gut instinct would be to try to solve something like this at an edge service instead of in Drupal. As in rewrite the final HTML based on the request params there, rather than nuking Drupal's optimisation systems
    – Clive
    May 25 at 12:26
3

You don't necessarily need to turn off aggregation if you want to remove all javascript. You could for example remove the placeholder in the html template, then the (already aggregated) javascript won't be replaced in the html page:

function mymodule_preprocess_html(&$variables) {
  if (MODULE_get_headers()) {
    unset($variables['#attached']['html_response_attachment_placeholders']['scripts']);
    unset($variables['#attached']['html_response_attachment_placeholders']['scripts_bottom']);
  }
  $variables['#cache']['contexts'][] = 'headers:my-header';
}

You need a cache context for the request header. This doesn't work for the Internal Page Cache, though. So you need to uninstall this module or extend it to add the request header to the cache key.

2
  • Yep. this is a much cleaner solution. But I don't understand why we need the cache contexts.
    – Binny
    May 25 at 13:50
  • 1
    This is caching two versions of the page, with and without javascript. Otherwise only one version is cached, whichever is first requested.
    – 4k4
    May 25 at 14:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.