Official documentation
- Adding stylesheets (CSS) and JavaScript (JS) to a Drupal 8 module
- Adding stylesheets (CSS) and JavaScript (JS) to a Drupal 8 theme
API changes
Note: hook_library of D7 has been replaced by hook_library_info at hook_library() and hook_library_alter() have been renamed to hook_library_info() and hook_library_info_alter()
-
hook_library_info()
is replaced by$extension.libraries.yml
files:Before
// jQuery Form Plugin. $libraries['jquery.form'] = array( 'title' => 'jQuery Form Plugin', 'website' => 'http://malsup.com/jquery/form/', 'version' => '3.39', 'js' => array( 'core/assets/vendor/jquery-form/jquery.form.js' => array(), ), 'dependencies' => array( array('system', 'jquery'), array('system', 'jquery.cookie'), ), ); // Dropbutton. $libraries['drupal.dropbutton'] = array( 'title' => 'Dropbutton', 'website' => 'http://drupal.org/node/1608878', 'version' => '1.0', 'js' => array( 'core/misc/dropbutton/dropbutton.js' => array(), ), 'css' => array( 'core/misc/dropbutton/dropbutton.css' => array(), 'core/misc/dropbutton/dropbutton.theme.css' => array(), ), 'dependencies' => array( array('system', 'jquery'), array('system', 'drupal'), array('system', 'drupalSettings'), array('system', 'jquery.once'), ), );
After
(Example from
system_library_info()
to/core/core.libraries.yml
)jquery.form: remote: https://github.com/malsup/form version: 3.39 js: assets/vendor/jquery-form/jquery.form.js: {} dependencies: - core/jquery - core/jquery.cookie # drupal.dropbutton: version: VERSION js: misc/dropbutton/dropbutton.js: {} css: component: misc/dropbutton/dropbutton.css: {} theme: misc/dropbutton/dropbutton.theme.css: {} dependencies: - core/jquery - core/drupal - core/drupalSettings - core/jquery.once
The path of each asset file is resolved relative to the directory of the registering extension. However, absolute paths (e.g.,
/core/assets/vendor/...
) as well as (stream wrapper) URIs (e.g.,http://example.com/foo.js
orpublic://color/bartik/color.css
) as well as protocol-free URIs (e.g.,//api.google.com/jquery.js
) are supported, too. Make sure you specify the resource as being "external". It is also a good idea to provide some additional information about the library. For example:angular.angularjs: remote: https://github.com/angular/angular.js version: 1.4.4 license: name: MIT url: https://github.com/angular/angular.js/blob/master/LICENSE gpl-compatible: true js: https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js: { type: external, minified: true }
The CSS asset file parent keys are mapping 1:1 to Drupal 8's CSS architecture documentation. Please refer to that documentation to learn more.
Side-benefit for maintenance:
Larger library declaration files (like
core.libraries.yml
) are able to leverage YAML references within the scope of the file, which works this way:jquery.ui: version: &jquery_ui 1.10.2 ... jquery.ui.accordion: version: *jquery_ui ... jquery.ui.autocomplete: version: *jquery_ui
-
hook_library_info_alter()
now acts on the (raw) library definitions, as declared in$extension.libraries.yml
files, and any performed manipulations are persistently cached.
API additions
-
The new
hook_library_alter()
allows modules and themes to act right before a specific library is attached and processed.This allows extensions to add request-specific and context-specific data to a particular library. For example:
- JavaScript settings: E.g., Locale module dynamically adds drupalSettings containing translations for the jquery.ui.datepicker library, which are only needed when the current language is not English.
- Additional asset files that should only be loaded when a particular library is attached. This use-case previously required developers to write complex
hook_js_alter()
implementations.
/** * Implements hook_library_alter(). */ function mymodule_library_alter(array &$library, $extension, $name) { if ($extension == 'core' && $name == 'jquery.ui') { // Add the backwards compatibility layer for jQuery UI. $library['dependencies'][] = array('mymodule', 'jquery.ui.compat'); // Add our additional stylesheet to improve the experience of jQuery UI. $path = drupal_get_path('module', 'mymodule'); $library['css'][$path . '/css/mymodule.jquery-ui.css'] = array('weight' => CSS_SKIN); } }
Note:
As you can see,
hook_library_alter()
uses the previously existing/internal format ofhook_library_info()
/drupal_add_library()
. The internal data structure of$library
might be revised prior to Drupal 8.0 — in particular, to retain the nested SMACSS category keys for CSS file assets, so as to avoid having to specify custom'group'
and'weight'
options.
Note that support for the 'every_page' option that used to be applicable for libraries, css and javascript has been removed.
Comments
hook_library_alter() has since been removed
See hook_library_alter() is removed in favour of hook_library_info_alter().
If you need to dynamically define a library, use hook_library_info_build()
If you need to make changes to a defined library, use hook_library_info_alter().
If you need to make per-request information available to a library, use drupalSettings (e.g. with hook_js_settings_alter())