Drupal 8 asset management using libraries.yml

One of the things you are likely to do if you write a custom module or a theme is include third party Javascript and/or CSS assets in it. Previously, this used to be a clumsy hook_library_info() array but is replaced by a YML file in D8. It makes asset management look more organized and easier to edit. Let's see how to do this for the colorbox module.

The new YML file will have the naming convention modulename.libraries.yml. So, ours will be colorbox.libraries.yml and will reside in the top level of the module directory like all other YML files.

Each entry has a unique name and a set of properties.

colorbox:
  version: VERSION
  js:
    js/colorbox.js: {}
  dependencies:
    - core/jquery
    - core/drupal

Here, colorbox is the name of the asset bundle to be included. This identifier will be used to refer the asset in the module or another yml file. The js property lists all the js files needed for the asset. The {} next to it can be used for specifying metadata like cache, preprocess, minify and weight.

An example entry from core.libraries.yml:

js:
  assets/vendor/classList/classList.min.js: { weight: -21, browsers: { IE: 'lte IE 9', '!IE': false }, minified: true }

The dependencies are the assets list which colorbox expects to be loaded. The core/jquery means the jquery asset present in core.libraries.yml.

Here's how the jquery entry looks in core.libraries.yml:

jquery:
  remote: https://github.com/jquery/jquery
  version: 2.1.3
  license:
    name: MIT
    url: https://github.com/jquery/jquery/blob/2.1.3/MIT-LICENSE.txt
    gpl-compatible: true
  js:
    assets/vendor/jquery/jquery.min.js: { minified: true, weight: -20 }

Likewise, the core/drupal dependency needs to be put up if the respective js exposes a Drupal setting.

Colorbox itself listed as a dependency in colorbox.libraries.yml for a theme variant:

stockholmsyndrome:
version: VERSION
js:
    styles/stockholmsyndrome/colorbox_style.js: {}
css:
    theme:
    styles/stockholmsyndrome/colorbox_style.css: {}
dependencies:
    - colorbox/colorbox
    - core/jquery
    - core/drupal

Including the assets in a page

The colorbox assets declared above can be included in a page by implementing the hook_page_attachments hook.

function colorbox_page_attachments(&$page) {
    ...
    $page['#attached']['library'][] = 'colorbox/colorbox';

Configurables can be passed from Drupal/PHP domain to js using the drupalSettings key.

    $js_settings = array(
      'opacity' => '0.85',
      'current' => t('{current} of {total}'),
      'previous' => t('« Prev'),
      'next' => t('Next »'),
      'close' => t('Close'),
      'maxWidth' => '98%',
    );
    $page['#attached']['drupalSettings']['colorbox'] = $js_settings;

Much of libraries.yml functionality overlaps with the hook_libraries_info of libraries module. The same thing can be accomplished by implementing the libraries_info hook, downloading colorbox jquery release in the libraries directory and calling:

libraries_load('colorbox', $variant);

In Drupal 7, this is the de facto way of handling third party js assets.

Why 2 ways to do the same thing?

The libraries module is also ported to Drupal 8 and can technically do the same thing, but offers 2 advantages:

  • The same asset can be used by more than 1 module. For example, colorbox jquery library can be used by both colorbox module and a custom theme.
  • Libraries module also facilitates loading of third party assets written in PHP.