How to include javascript on single pages in Drupal 8 in a way that is amenable to scale.

12

Following Steps will make working with External JavaScript libraries in Drupal 8 absolutely clear (including how to conditionally load it in specific pages):

Step 1: Place the JavaScript file in your theme or module inside a folder called js. After this step your folder structure must look like :

my-theme/js/my-script.js
Step 2: If your theme already has a my-theme.libraries.yml file open it, if not create it.

In Drupal 8 Libraries are simply collections of CSS or JS files bundled together under a uniquely identified library name.

In this step we need to include the JS file that we created in step 1 in our library. we do it by adding following lines of code in our my-theme.libraries.yml file.

my-library:
js:
js/my-script.js: {}
Now we have an asset library called my-theme/my-library which can be loaded to our site in several ways.

Step 3: Final step is to load the library in our site. This can be done in 4 specific ways:

Way 1: Attach library globally via theme-name.info.yml file

Libraries can be specified in the theme-name.info.yml file by adding it to the libraries property, like this:

name: my-theme
type: theme
description: my theme
package: other
core: 8.x
libraries:
- my-theme/global-effects
- my-theme/my-library

base theme: stable
Any libraries specified here in the themename.info.yml file will be made available on evey page.

Way 2: Using hook_page_attachments_alter in theme-name.theme file.

Following lines of code will attach our library only to the node listing page.

function mytheme_page_attachments_alter(&$page){
$path = $current_path = \Drupal::service('path.current')->getPath();
if($path == '/node') {
$page['#attached']['library'][] = 'my-theme/my-library';
}
}
Way 3: Another useful way to conditionally add a library is by using a preprocess function like hook_preprocess_page().

Here's another example of restricting our asset libray to the front page

function mytheme_preprocess_page(&$variables){
if ($variables['is_front'] == TRUE) {
$variables['#attached']['library'][] = 'my-theme/my-library';
}
}
Way 4: Asset libraries can also be attached from within a Twig template using the attach_library function. Anytime that template is used the corresponding library will be attached in accordance with any template-specific conditions.

In order to see this in action, we need to create or modify a template in our theme. In this example let us modify node.html.twig template to attach our library only if node.id == 1 with following lines of code

{% if node.id == 1 %}
{{ attach_library('my-theme/my-library') }}
{% endif %}
With this in place, visiting node 1 in our site, we will be able to see our library in action.