How to add custom javascript in Magento 2 with requireJS

How to add custom javascript in Magento 2 with requireJS

Magento 2 brings some new features in javascript. One of them is “requireJS” (javascript file loader) and second is “jQuery“, a very popular js library. One of the biggest benefits is using requireJS which means that Magento 2 is ready for the upcoming HTTP2 protocol. In the next few steps we will explain how to create valid javascript code for use in requireJS. Let’s start with an example.

As usual, we need to create a valid Magento 2 module like seen on the screen shoot below:

js_modul

You may notice some differences between Magento 1 and Magento 2 in the fact that all javascript, layout and template phtml files now belong to the module. Also, our javascript files are in our module located on the directory path: “app/code/Inchoo/Js/view/frontend/web/js/“. For this example we created two js files: “inchoo.js” and “logger.js

Take a look at our javascript code which is valid for using in requireJS environment.

define([
    "jquery",
    "logger",
    "jquery/ui"
], function($, logger) {
    "use strict";
    logger.log('inchoo.js is loaded!!');
    logger.log(logger);
 
        //creating jquery widget
        $.widget('inchoo.js', {
            _create: function() {
 
                //options which you can pass from js.phtml file in json format
                logger.log(this.options);
 
                //access to element p#test
                logger.log(this.element);
 
                //for exmple, you can create some click event or something else
                this.element.on('click', function(e){
                    logger.log("You click on element: " + e.target);
                });
            }
 
        });
 
    return $.inchoo.js;
});

You will notice that the javascript code on the top uses “define” function.

This function is from requireJs – first parameter of “define” function is array of dependency and second parameter is definition of our function.
Definition function should always return an object. In our example our function returns “$.inchoo.js”.
You can read more about define function on url: http://requirejs.org/docs/api.html#define

In our example, our javascript uses jQuery, jQueryUI and logger. All dependency should be declared in “define” function. You can see that we put as the first argument next array:

["jquery", "logger", "jquery/ui"]

In definition of our function we created jquery widget and we put all logic in widget constructor “_create“. JQuery and logger are passed as next parameters: “$” and “logger”.

Source code of our logger class is below. You can notice that our class doesn’t need any dependency and that in “define” function there’s only definition function which returns object as we mentioned before.

define(function() {
    "use strict";
 
    return {
        log : function(param){
            console.log(param);
        }
    };
});

All files should be declared in “requirejs-config.js” file – this is config file which uses requireJs.

var config = {
    map: {
        '*': {
            inchoojs:      'Inchoo_Js/js/inchoo',
            logger:      'Inchoo_Js/js/logger'
        }
    }
};

Next step will be to explain how to load and use our javascript. In order to use/load our javascript, you have to add the next code in some phtml file. Our complete example of js.phtml file is below:

Test element
<script type="text/x-magento-init">// <![CDATA[ { "#test": { "Inchoo_Js/js/inchoo": {"url":"http://www.example.url", "method":"post"} } } // ]]></script>

In Magento 2 there is a javascript parser (located in script “lib/web/mage/apply/scripts.js”) which reads script tags with attribute type=”text/x-magento-init” and load/process them with “child” json data in curly brakets:

"#test": {
            "Inchoo_Js/js/inchoo":
                {"url":"http://www.example.url", "method":"post"}
	}

You will notice “#test“, this is id of html element which is passed to jquery widget and it is available in our script, over property “this.element“. Other elements “url” and “method” are options which are also passed from json object to our widget and these options are available in the script over js property “this.options“. These options can be defined as you want.

If you did everything as above, javascript should work and you should have a script tag in html head like in a screen shot below 🙂 .

javascript

If this or anything else regarding Magento development confuses you, we will gladly check out your site and offer technical insights on what to improve based on our detailed custom report. Feel free to get in touch!

Related Inchoo Services

You made it all the way down here so you must have enjoyed this post! You may also like:

Magento 2 Customer Groups Configuration Josip Kovacevic
Josip Kovacevic, | 2

Magento 2 Customer Groups Configuration

Javascript Bundling in Magento 2 Nenad Andrakovic
Nenad Andrakovic, | 18

Javascript Bundling in Magento 2

How to use Knockout in Magento 2 Domagoj Potkoc
Domagoj Potkoc, | 23

How to use Knockout in Magento 2

15 comments

  1. Hi,

    I have purchased a small javascript based design editor which I would like to load when a given theme page is visited. I kep reading various posts but I can’t seem to get the js files or the css files to load on the module’s page.

    Can anyone please help me with some advice on how to approach this problem. This design editor also features some css design and is basically a standalone webpage.

    Thanks

  2. I truing to load my main.js on home and cart page only , currenlty it is loading on all pages , can any one knows how to load on specify pages in custom module .

    var config = {

    deps: [
    "NameSpace_ReviewRating/js/main",
    ],

    map: {
    '*': {
    'slickjs': 'NameSpace_ReviewRating/js/slick/slick',
    'sliderjs': 'NameSpace_ReviewRating/js/slick/tiny-slider'

    }
    },

    shim: {
    "slickjs": ["jquery"],
    "sliderjs": ["jquery"]
    }

    };

  3. "#test": {
    "Inchoo_Js/js/inchoo":
    {"url":"http://www.example.url", "method":"post"}
    }

    can be shorted to:?
    "#test": {
    "inchoojs":
    {"url":"http://www.example.url", "method":"post"}
    }

    1. How are you loading the js.phtml? What little magic piece am I missing? YES, what goes in the default.xml? Obviously not a block because you didn’t include any block classes. Doesn’t requirejs-config.js have to go in /frontend and not frontend/web to get it to actually load?

  4. hmm. It`s strange because I have problem with .phtml step
    //
    still getting errors about :
    Uncaught SyntaxError: Unexpected token /
    two slashes before CDATA are causing this error.
    Any ideas why ?

    1. Got this solved by removing comments.

      I had something like this
      “componentName”: {} //comment

      taking the co
      “componentName”: {}

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.

Tell us about your project

Drop us a line. We'd love to know more about your project.