There is an entire ecosystem of third-party Javascript libraries at one's disposal when writing a Drupal frontend. No need to reinvent the wheel, right? But how do you integrate them into your project? In this article, we'll describe four possible ways to do this, starting with the least optimal and moving toward the best.
Approach 1: Embed a script tag in the theme template
This approach involves the least amount of Drupal knowledge and the least amount of work. It is effective and completely valid, but it doesn't benefit from the rest of the Drupal system.
To follow this approach, locate the html.html.twig file in the active theme. If there is none, copy it out of the parent theme. This document contains the <head> and <body> HTML tags. Simply insert a fully formed <script> tag where it should show up.
This approach is great for placing code snippets from third-party sites for tracking and analytics. But it is tied to the current theme, can't be manipulated in other parts of Drupal, and can't use Drupal configuration values.
Approach 2: Drupal library with locally saved file
This approach, as well as the next two approaches, all use the Drupal library system. Using the Drupal library system allows the JS library to be used across several themes and be manipulated by other parts of Drupal. This particular version involves saving the source of the JS library to the local filesystem and referencing it within a libraries yaml file.
For instance, if you wanted to use lodash in a custom module, save lodash.js inside the module, perhaps inside a folder named js.
js/lodash.js
Then create or modify a libraries yaml file in the custom module and create an entry for it. In a module called "custom:
lodash:
js:
js/lodash.js: {}
Now the library is ready to be used in your context.
The benefit of this approach, as opposed to the approaches below, is that it isn't reliant on a CDN or package manager repo being up and running. The disadvantage is that the file is hosted on your server versus a fast CND, the file takes up space in your version control repository, and is locked to the particular version you saved.
Approach 3: Drupal library with Composer and Asset Packagist
This approach is an expansion of approach 2. Instead of saving the file locally, you pull it down with Composer, which is already being used for Drupal core. By using the Asset Packagist composer repo, you can have composer manage JS libraries that are in the NPM ecosystem. A properly configured composer.json file will save the JS library somewhere accessible by the Drupal library system. The example lodash.sh Drupal library definition will look something like this:
lodash:
js:
/libraries/lodash/lodash.js: {}
This approach gains the ability to pin the library to only major versions and it doesn't involve checking the file into version control. But the file is still served by your web server.
Approach 4: Drupal library with CDN
This approach results in yet another Drupal library definition, but it relies on a CDN to serve the library. One great CDN option is JSDeliver. We point the Drupal library definition to the CDN to make this work:
lodash:
js:
https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js: { type: external, minified: true }
This approach can still pin to as specific a version as necessary. It also doesn't require additional steps with Composer. And while it results in serving up the file from a super-fast CDN, it introduces a dependency. If the CDN should ever suffer an outage, the library will be unable to load.
There you have it: Four approaches to adding a JS library to Drupal. I go back and forth between option 3 and option 4. What approach do you recommend? Tell us on Twitter.