Add JavaScript to Your Theme or Module
Prerequisites
A working theme or module. If you don't have a theme or module, you should start with Creating custom modules or Theming.
Basics
There are two basic steps to including JavaScript in your theme or module:
- Define a library
- Attach the library to an entity.
Note: A module/theme name of ‘example’ will be used in all examples.
Defining a library
In your theme or module’s root directory create a *.libraries.yml file. An example example.libraries.yml file would be:
example:
version: 1.x
js:
js/example.js: {}
js/example2.js: { minified: true }- The root element
exampleis usually the namespace of your project but it can be anything you want since you can define numerous libraries in a project. - Declare a version of the library.
- Include JavaScript files with the
jselement. This will hold an array of JavaScript files and their associated properties. - Beneath that declare the path from the project root to the file. The filename forms the key of the array of JavaScript files.
For each file, you can define a number of properties. If you don't wish to nominate any custom properties, then you must provide an empty array {} like the example above. Some examples properties you could add include:
external: bool (load the script from an external source)minified: bool (tells Drupal it needn’t try to compress the script)preprocess: bool (tells Drupal if it should be preprocessed (disable aggregation)
Attaching the File
Attaching a library can be done in several ways depending on your needs. Remember that the library is always registered by its module or theme name followed by the library name. In this case, it would be 'example/example'.
- module: hook_element_info_alter()
- module: hook_page_attachments()
- theme: template_preprocess_HOOK()
- twig:
{{ attach_library('example/example') }}
hook_page_attachments() and template_preprocess_HOOK() operate exactly the same way as seen in this example:
function example_preprocess_node__page(array &$variables) : void {
// Theme name: 'example', library name: 'example'.
$variables['#attached']['library'][] = 'example/example';
}In the case of hook_element_info_alter() you would need to specify the type you would like the JavaScript library to always be attached to. If you wanted a library attached to all cases where radio buttons are used you could do:
function d8_theme_element_info_alter(array &$info) : void {
if (isset($info['radio'])) {
$info['radio']['#attached']['library'][] = 'example/example';
}
}Include Dependencies
If your JavaScript depends on any other resources, like jQuery (included with Drupal) or Drupal settings you can use dependencies:
example:
version: 1.x
js:
js/example.js: {}
dependencies:
- core/jquery
- core/drupalSettingsIf you wished to quickly add to drupalSettings before it gets passed to the library, you could modify it like so:
function d8_module_page_attachments(array &$attachments) {
$attachments['#attached']['library'][] = 'example/example';
$attachments['#attached']['drupalSettings']['example']['foo'] = 'bar';
}Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion
Still on Drupal 7? Security support for Drupal 7 ended on 5 January 2025. Please visit our Drupal 7 End of Life resources page to review all of your options.