45

I've read 3 pages of Google Results on how to load a JS file for all pages and still am not able to do it.

I've got a few doubts, hope somebody can clear them out.

  1. Do I need to create a module inside app/code with the requirejs-config.js ? Or I can put a requirejs-config.js inside my theme instead?

  2. What should I put inside requirejs-config.js ?

  3. What should the code look like inside my .js file? I saw that you can't use jQuery's document.ready and you must have a define([

  4. What should I put inside define([ ?

  5. If I've got third party jQuery modules, do I have to edit them to make them work?

  6. Do I need to put xml somewhere to tell magento that my.js file exists?

  7. If I create a module inside app/code with all the js code there, would it include all the stuff in all pages? How can I achieve that?

8 Answers 8

86

To load a custom main.js file on all pages (in the RequireJS-way) this is a good way:

1) Create main.js

Create main.js within the theme folder

<theme_dir>/web/js/main.js

with this content:

define([
  "jquery"
], 
function($) {
  "use strict";

  // Here your custom code...
  console.log('Hola');

});

In short: we declare dependencies at the start, e.g. "jquery". We define as function's parameter the variable name for using the dependency within the function, e.g. "jquery" --> $. We put all our custom code within function($) { ... }.

2) Declare main.js with a requirejs-config.js file

Create a requirejs-config.js file within the theme folder:

<theme_dir>/requirejs-config.js

with this content:

var config = {

  // When load 'requirejs' always load the following files also
  deps: [
    "js/main"
  ]

};

"js/main" is the path to our custom main.js. The ".js" extension is not required.

Our requirejs-config.js will be merged with other requirejs-config.js defined in Magento.

RequireJS will load our main.js file, on each page, resolving dependencies and loading files in an async way.


Optional: Including third-party library

This is the way to include third-party libraries.

1) Add the library in web/js:

<theme_dir>/web/js/vendor/jquery/slick.min.js

2) Open requirejs-config.js and add this content:

var config = {

  deps: [
    "js/main"
  ],

  // Paths defines associations from library name (used to include the library,
  // for example when using "define") and the library file path.
  paths: {
    'slick': 'js/vendor/jquery/slick.min',
  },

  // Shim: when you're loading your dependencies, requirejs loads them all
  // concurrently. You need to set up a shim to tell requirejs that the library
  // (e.g. a jQuery plugin) depends on another already being loaded (e.g. depends
  // on jQuery).
  // Exports: if the library is not AMD aware, you need to tell requirejs what 
  // to look for so it knows the script has loaded correctly. You can do this with an 
  // "exports" entry in your shim. The value must be a variable defined within
  // the library.
  shim: {
    'slick': {
      deps: ['jquery'],
      exports: 'jQuery.fn.slick',
    }
  }

};

It looks more complicated than what it actually is.

3) Add the dependency within main.js:

define([
  'jquery',
  'slick'
], 
function($) {

  // ...

});
10
  • Hi , Can you tell if I have to include bootstrap.js here. How can I add it so that bootstrap works well in my theme. Thanks!
    – anujeet
    Feb 27, 2017 at 14:06
  • 1
    @anujeet You can include bootstrap.js in the same way I included slick.js in the above example. For the shim value you can try to use this: 'bootstrap': { deps: ["jquery"], exports: '$.fn.popover' }, as explained here: stackoverflow.com/a/13556882/3763649
    – Andrea
    Feb 27, 2017 at 17:59
  • See my require-config.js var config = { deps: [ "js/animate", "js/incase", "js/confetti" ], paths: { "jquery.bootstrap":"js/bootstrap.min" }, shim:{ 'jquery.bootstrap':{ 'deps':['jquery'] } } }; require(["jquery",'jquery.bootstrap', 'jquery/ui', 'jquery/validate', 'mage/validation/validation', 'domReady!']); My minicart stops working with this
    – anujeet
    Feb 28, 2017 at 6:57
  • @anujeet Better you open another question with this issue, reporting your require-config.js and if you have some errors in the javascript console. If you link your question here I will be glad to help you :)
    – Andrea
    Feb 28, 2017 at 8:58
  • 1
    Man, you saved my life. Works fine here. Thanks
    – w3debugger
    Nov 21, 2017 at 14:50
6

Duplicate the file:

app/code/Magento/Theme/view/frontend/layout/default_head_blocks.xml

To

app/code/your_vendor/your_theme/Magento_Theme/layout/default_head_blocks.xml

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <!-- Add local resources -->
        <css src="css/my-styles.css"/>

        <!-- The following two ways to add local JavaScript files are equal -->
        <script src="Magento_Catalog::js/sample1.js"/>
        <link src="js/sample.js"/>

        <!-- Add external resources -->
        <css src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css" src_type="url" />
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js" src_type="url" />
        <link src="http://fonts.googleapis.com/css?family=Montserrat" src_type="url" /> 
    </head>
</page>

For more information:

http://devdocs.magento.com/guides/v2.0/frontend-dev-guide/layouts/xml-manage.html

Good luck!

BTW read the frontend devdocs official from magento to get the basic :)

1
  • Because Bootstrap's script requires JQuery to be initialized, including it in the head won't work. Read this official doc. for more info. :)
    – V.S
    Jan 26, 2017 at 18:23
5

You can add JS files using xml as below. This will add js in all the pages.

With custom module:

Create default.xml file in your module.

app/code/vendor_name/module_name/view/frontend/layout/default.xml

<?xml version="1.0"?>
<page xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <head>
        <!-- Add js using link tag-->
        <link src="js/script.js"/>

        <!-- Add js-->
        <script src="Vendor_Module::js/script.js"/>

        <!-- Add external js -->
        <script src="https://apis.google.com/js/platform.js" src_type="url" />
   </head>
</page>
3

The method of adding js using the default_head_blocks.xml file will not work for 3rd party JQuery plugins. So, if you want to add custom JQuery plugins and use them, you will need to use requirejs-config.js file.

To answer your questions one by one:

1) & 2) You don't need to create a module to add the requirejs-config.js file. You can just add it in this location:

app/design/frontend/<Vendor>/<theme>/requirejs-config.js

Refer to this answer to creating a proper requirejs-config.js file.

3) You will need to list the dependencies of your js file before you write your scripts.

require([
  'jquery',
  'jquery/ui'
], function($){
   // ... Your code here
}); 

The above code says that you will need jquery and jquery ui for your scripts.

4) You don't need to use the define([ unless you are creating a javascript plugin.

5) No, you don't need to edit them but you will need to specify their dependency using the requirejs-config.js file. If you have owl.carousel.min.js in <vendor>/<theme>/web/js/owl.carousel.min.js, your requirejs-config.js file will look like this:

var config = {
    map: {
        '*': {
            owlCarouselTheme: 'js/owl.carousel.min'
        }
    },
    shim: {
        owlCarouselTheme: ['jquery']
    }
};

In the above code, please remember that there is no .js for the file. And now to use it in your js

require(['jquery', 'owlCarouselTheme'],function($){
    $(document).ready(function() {
        $(".footer.links").addClass("owl-carousel").owlCarousel({items: 1});
    });
})

If everything works well, you should have your footer links in a slider.

6) & 7) Just use the method suggested by @Goldy to add your js. It will add your js file to all the pages.

For further reading, you can look at this post

Hope this helps.

1
2

Load a JS file for all pages

app/code/VendorName/ModuleName/view/frontend/layout

default_head_blocks.xml

<?xml version="1.0"?>

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <script src="VendorName_ModuleName::js/main_all_page.js" />
    </head>
</page>

app/code/VendorName/ModuleName/view/frontend/web/js

main_all_page.js

require(["jquery"],
    function($){

    alert("JS file for all pages ");
    console.log("JS file for all pages ");

})

I Hope This Helps You.

1

This is how I add dotdotdot library in my magento2 custom theme.

1. Download and add Js Library in your theme following the path:

// app/design/frontend/Namespace/themename/web/js/jquery.dotdotdot.min.js

2. Create a theme's requirejs file as follow and let the requirejs know newly added library.

// app/design/frontend/Namespace/themename/requirejs-config.js
var config = {
   map: {
       '*': {
           dotdotdot: 'js/jquery.dotdotdot.min',
       }
   }
};

3. Use the added library in your theme's main js file as follow:

// app/design/frontend/Namespace/themename/web/js/main.js
require([ 'jquery' , 'dotdotdot' , 'domReady!'],function($){
    $(window).load(function() {
        //custom js code
        /* $(".product-item-name").each(function(){
            $(this).dotdotdot(); 
        }); */
    });
});

4. and include your theme's js file in your site's head as follow:

// app/design/frontend/Namespace/themename/Magento_Theme/layout/default_head_blocks.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <link src="js/main.js"/> 
    </head>
</page>

You can add any external JS library and custom file on every page in magento2.

5
  • I have tried this is admin side, js is coming correctly but expected result is not coming
    – Naveenbos
    Sep 18, 2017 at 12:44
  • Nice answer. Gonna try it. Is there a way to specify a certain page where the js file is needed.? Mar 14, 2019 at 12:53
  • For a specific page, move the "default_head_blocks.xml" content in above example to your specific layout file. For example in case of product detail page, add that xml in app/design/frontend/Namespace/themename/Magento_Catalog/layout/catalog_product_view.xml Mar 15, 2019 at 2:58
  • @saiid, Is this a better way to include a sinle custom JS in the header than overriding header.phtml May 10, 2020 at 18:29
  • @CodeForGood yes it is always better to follow the practice that Magento recommends. Like you never know in future you're going to add more custom JS libraries. May 12, 2020 at 1:53
0

May be this one help anyone, add this code to your default.xml file

you can add this to your theme or your module.

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
    <head>
    <script src="Company_Module::js/custom.js"/>
</head>
</page>

your custom.js file would reside in the location app/code/Company/Module/view/frontend/web/js/custom.js

0

I'd suggest simple way that requires no coding and no editing - go to Admin->Content->Configuration-> Select Website and Edit -> HTML Head and include or tag here, you can insert CSS also here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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