Change record status: 
Project: 
Introduced in branch: 
8.x
Introduced in version: 
8.0.0-beta4
Description: 

hook_library_alter() is a hook that executes during run-time in order to make adjustments to asset library definitions. (hook_library() in Drupal 7, libraries.yml in Drupal 8).

Using it is sub-optimal because:

  1. it violates the principle that libraries are declarative, because it effectively makes them different depending on the request
  2. it causes performance problems, due to the invoking of hook_library_alter() on each page load, for every single library, for as many implementations of the hook there are
  3. (practical example of point 1) it encourages (or at least allows) for things that actually belong in drupalSettings (such as modifying configuration based on the current site language like locale_library_alter())
  4. it creates confusion with hook_library_info_alter(), a similar hook that executes at cache rebuild time instead, for better performance.

Since Drupal 8 now supports a JS settings asset type, and a corresponding hook_js_settings_alter() to alter JS settings for the current request), we no longer require this hook in order for libraries to react dynamically. Therefore, modules should no longer use hook_library_alter(), opting instead for hook_library_info_alter(), perhaps in combination with hook_js_settings_alter(), as appropriate.

Drupal 7


function locale_library_alter(&$libraries, $module) {
  if ($module == 'system' && isset($libraries['ui.datepicker'])) {
    global $language;
    // locale.datepicker.js should be added in the JS_LIBRARY group, so that
    // this attach behavior will execute early. JS_LIBRARY is the default for
    // hook_library_info_alter(), thus does not have to be specified explicitly.
    $datepicker = drupal_get_path('module', 'locale') . '/locale.datepicker.js';
    $libraries['ui.datepicker']['js'][$datepicker] = array();
    $libraries['ui.datepicker']['js'][] = array(
      'data' => array(
        'jquery' => array(
          'ui' => array(
            'datepicker' => array(
              'isRTL' => $language->direction == LANGUAGE_RTL,
              'firstDay' => variable_get('date_first_day', 0),
            ),
          ),
        ),
      ),
      'type' => 'setting',
    );
  }
}

Drupal 8

The first alter hook changes the definition of the library. The second then replaces the placeholder values for the drupalSettings stored in the library definition for each request.

 /**
 * Implements hook_library_info_alter().
  *
  * Provides the language support for the jQuery UI Date Picker.
  */
function locale_library_info_alter(array &$libraries, $module) {
  if ($module === 'core' && isset($libraries['jquery.ui.datepicker'])) {
    $libraries['jquery.ui.datepicker']['dependencies'][] = 'locale/drupal.locale.datepicker';
    $libraries['jquery.ui.datepicker']['drupalSettings']['jquery']['ui']['datepicker'] = [
      'isRTL' => NULL,
      'firstDay' => NULL,
    ];
  }
}

/**
 * Implements hook_js_settings_alter().
 *
 * Generates the values for the altered core/jquery.ui.datepicker library.
 */
function locale_js_settings_alter(&$settings) {
  if (isset($settings['jquery']['ui']['datepicker'])) {
    $language_interface = \Drupal::languageManager()->getCurrentLanguage();
    $settings['jquery']['ui']['datepicker']['isRTL'] = $language_interface->getDirection() == LanguageInterface::DIRECTION_RTL;
    $settings['jquery']['ui']['datepicker']['firstDay'] = \Drupal::config('system.date')->get('first_day');
   }
 }
Impacts: 
Module developers