1

I'm using magento 2 and I'm trying to add a content slider on the about us page ,and to do that I need to include the js library , I've tried to do that by adding this

 <reference name="head">
   <action method="addJs">
     <script>library.js</script>
   </action>
 </reference> 

to design tab of my page , but still doesn't work..

2
  • Can u please share code at design tab.
    – Amit Bera
    May 6 '16 at 10:54
  • '<reference name="head"> <action method="addJs"> <script>myjslibrary.js</script> </action></reference>' and my js file is in my www folder..
    – alexcr
    May 6 '16 at 10:56
6

I wouldn't advise adding JS via the XML anymore, Magento 2 best practices are to use Require JS. Read more about that here.

For a quick simple method read the answer on this question - If you want some more explanations than read my answer.

If you really don't want to use Require JS then scroll to the bottom of my answer for the XML method.


Please note that I'm no expert when it comes to Require JS, this is working for me and I believe it is best practice or close to it. But please read the docs linked above before doing it yourself.

As the slider is likely to be used again I recommend creating it as a module that can easily be reused via Require JS. I usually add Require scripts via the script tag, it can be done via the data-mage-init attribute but I find that a bit messy compared to the script tag.

In my case I added the following files:

app/design/frontend/*VENDOR*/*THEME*/requirejs-config.js
app/design/frontend/*VENDOR*/*THEME*/web/js/carousel.js
app/design/frontend/*VENDOR*/*THEME*/web/js/vendor/bootstrap/carousel.js
app/design/frontend/*VENDOR*/*THEME*/web/js/vendor/bootstrap/transition.js

In your template file

You need to tell require when to load the script, and what script to load. In my example below whenever the class slider-class-or-id-here is loaded in the DOM the script carousel-init will run.

I added this to my custom template for the homepage - app/design/frontend/*VENDOR*/*THEME*/Magento_Cms/templates/homepage/homepage-carousel.phtml

<script type="text/x-magento-init">
    {
        ".slider-class-or-id-here": {
            "slider-script-here": {}
        }
    }
</script>

You can also pass some options within the script tag but it isn't required.

You could end the answer with this point and simply link to your carousel's JS file, although that isn't the preferred method (IMO and according to Magento's dev docs).

Initialising the slider

If your chosen slider has a different method of initialising (e.g by adding a class already defined) then this isn't required.

As the slider/carousel isn't limited to just CMS pages or product pages I have added the init script to app/design/frontend/*VENDOR*/*THEME*/web/js/carousel.js.

The script below tells Require that this script depends on jQuery and bootstrap-carousel (which is defined later in my answer). Then it initialises the slider/carousel passing an interval option.

// Script to initialise any element with the .slider-class-or-id-here class
//
// DEPENDENCIES
// Depends on jQuery and bootstrap-carousel (which is defined in app/design/frontend/*VENDOR*/*THEME*/requirejs-config.js)

define(['jquery', 'bootstrap-carousel'], function($) {
    $('.slider-class-or-id-here').carousel({
        interval: 3000
    });
});

Defining the scripts as Require modules

Then we need to tell Require JS about our modules and map the scripts to a module name. I believe this can be done at a site level, theme level, or module level. I chose theme level in this case so I created this file - app/design/frontend/*VENDOR*/*THEME*/requirejs-config.js

This config tells Require that we have 3 modules, bootstrap-carousel, bootstrap-transition, and carousel-init and where they are located (we leave out the .js suffix). Then we tell it we have some none AMD (not using require) scripts that have dependencies, so js/vendor/bootstrap/carousel depends on jquery and bootstrap-transition, and js/vendor/bootstrap/transition depends on jquery.

You can ignore the bootstrap-transition by the way this is something I required, unless you're using Bootstrap you won't need it.

// Map our module names to their relevant script
var config = {
    "map": {
        "*": {
            "bootstrap-carousel": "js/vendor/bootstrap/carousel",
            "bootstrap-transition": "js/vendor/bootstrap/transition",
            "carousel-init": "js/carousel"
        }
    },

    // Define dependencies for none AMD third party modules - Do not use for scripts that use require - http://requirejs.org/docs/api.html#config-shim
    "shim": {
        "js/vendor/bootstrap/carousel": ["jquery", "bootstrap-transition"],
        "js/vendor/bootstrap/transition": ["jquery"]

    }
};

Some points

  • This is indeed more difficult than simply adding a script via the XML, but Magento have upped their game with Magento 2 and developers are required to learn quite a few more technologies. It will also make life easier further down the road when you have more scripts with more dependencies.
  • This is a pretty confusing topic and it wouldn't surprise me if my answer raises my questions than answers, if you have any questions/problems feel free to get in touch (applies to anyone). My twitter handle is on my profile.

If you really want to do it the XML way (not recommended)

If you really want to go down the XML route and don't want to use Require JS you will need to use the following XML.

<head>
    <script src="*PATH TO YOUR SCRIPT" />

    <!-- External scripts -->
    <script src="URL-HERE" src_type="url" />
</head>

More parameters can be seen in the XML docs

4
  • Big help! This all works perfectly, thank you Ben! Aug 12 '19 at 16:02
  • This does not answer how to add JS to a specific page. To do so, use XML. This does not preclude using RequireJS in the linked file.
    – jiheison
    Sep 27 '20 at 23:12
  • @jiheison This method is adding JS to a template, so the JS will load whereever that template renders. If you only want it on one page, only load the template on one page. If you want it to load everywhere, load the template everywhere.
    – Ben Crook
    Sep 28 '20 at 8:44
  • Right. This answer has good info. But I think that the most direct answer is still to use XML. Adding it to a template requires overriding a template or adding a new block/template. But executing a script on a specific page doesn't necessarily involve either, in which case these would be extra steps.
    – jiheison
    Sep 28 '20 at 10:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.