26

Is it possible to include a requirejs-config.js file (or otherwise configure RequireJS) via a Magento theme? Or is the capability reserved for Magento modules? The dev docs information on theme structure is ambiguous to this point.

Dev docs doesn't mention anything about RequireJS -- however, themes do include a web which means javascript can be bundled with them. If javascript can be bundled with a theme, that means a RequireJS module can be bundled with a theme, and if a RequireJS module can be bundled with a theme that module may requires a specific RequireJS configuration.

My naive assumption would be themes would have this capability, but I haven't been able to find any documentation on this one way or the other, and haven't an afternoon free to spend doing the required code spelunking on Magento's requirejs-config.js file including.

2

4 Answers 4

14

you can actually include a require-config.js in your themes Module dirs.

The problem is (actually for our frontend team) that there seems to be no possibility, to override the config, but to extend the config.

So, to take the Magento_Theme module for an example here, if you add a require-config.js under <theme_base_dir>/Magento_Theme dir, the config will be added to the generated require-config.js file and also the config from the Magento_Theme module will be added.

To answer your question I also tried to add a require-config.js under the themes <theme_base_dir>/web dir and also under the themes root dir. Both did not work. update: actually according to the answer below, it is possible by placing it into the theme base dir

So the answer would be basically yes, since you could add any js requirement under any module (theme related js files may be best placed under the <theme_base_dir>/Magento_Theme dir)

Although I would say, there should be the possibility to add a theme related require-config.js outside of any Module (maybe you deactivate the given module) and also it should be possible to override a modules require-config.js.

Both seem not possible atm.

===UPDATE===

actually it seems possible to have a theme specific require-config.js. See @Gareth Daine's Answer below

8
  • Re: "under the Magento_Theme" could you be more explicit -- it's not 100% clear which folder in a theme and/or module your'e refering to. Explicit meaning path/to/theme/files/[etc/Magento_Theme Feb 13, 2016 at 22:39
  • I meant the acutal module override in your theme. So for the module Magento/Theme the require-config.js would be <theme_base_dir>/Magento_Theme/require-config.js where Magento_Theme is the actual module name Feb 13, 2016 at 22:43
  • nice, updated the answer to make it more clear Feb 13, 2016 at 23:05
  • So, am I right in thinking that a requirejs-config.js file does not work under app/design/frontend/<Vendor>/<theme>/web/js? Feb 23, 2016 at 14:32
  • 1
    Check my answer below. You're not supposed to place it in the web directory. It should go in your theme root directory. Feb 24, 2016 at 10:54
18

OK, I think I may have solved it and I believe that the documentation is ambiguous and needs updating to clarify the process.

I moved my requirejs-config.jsfrom within the web/js and web directories respectively for both Magento_Theme and the root of my theme at <Vendor>/<theme> and now my RequireJS config is merged into the main requirejs-config.js with all other includes.

So, it appears that you have to include the requirejs-config.js file in the following locations based on the theme/module requirements.

Theme Level

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

Module Level

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

So, in your requirejs-config.js for your theme you should map your component to a path and then use shim to declare any dependencies:

var config = {
    map: {
        'component': 'js/component'
    },
    shim: {
        'component': {
            deps: ['jquery']
        }
    }
};

Then you'll need to create a template to hold the initialisation of the components via a <script> tag (unless you attach it directly to an element within a .phtml file) if this is the route you want to go down, include the following content:

<script type="text/x-magento-init">
    {
        "*": {
            "js/component": {} // Not entirely sure what {} is and what I'm passing here
        }
    }
</script>

Alternatively, bind it to an element:

<script type="text/x-magento-init">
    {
        "#element": {
            "js/component": {} // Not entirely sure what {} is and what I'm passing here
        }
    }
</script>

Then simply include the .phtml template in your layout instructions, for example, I placed mine within the default.xml located at app/design/frontend/<Vendor>/<theme>/Magento_Theme/layout under the body node and referenced:

<block class="Magento\Framework\View\Element\Template" name="theme.js" template="Magento_Theme::html/js.phtml" />

2
  • The {} in "js/component": {} is used to pass options to the component Nov 2, 2016 at 8:29
  • This should be considered the right answer. As a completement, if you want to init the component from a .phtml just add the following: <script type="text/javascript" > require(['js/component']); </script>. Feel free to use if/else validation in PHP as you required. Jul 21, 2020 at 10:25
5

Yes requirejs-config.js can be added to theme as follow. 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.

2
  • I tried adding a library via the requirejs-config.js this way. However, RequireJS then tries to load js/some.library.js from the root instead of from the theme directory.
    – fritzmg
    Feb 12, 2018 at 14:26
  • Ah, you have to omit the .js extension... silly :)
    – fritzmg
    Feb 12, 2018 at 16:14
3

Didn't have sufficient rep to make this a comment, but just to note that Gareth's answer didn't quite work for me.

var config = {
    map: {
        '*': {
            'component': 'js/component'
        }
    },
    shim: {
        'component': {
            deps: ['jquery']
        }
    }
};

Wrapping the 'component': 'js/component' with '*':{} did the trick.

Also rather than create a template file I added the code below at the top of app/design/frontend/<Vendor>/<theme>/Magento_Theme/layout/default.xml

    <referenceContainer name="after.body.start">
        <block class="Magento\Framework\View\Element\Text" name="jquery.bootstrap">
            <arguments>
                <argument translate="true" name="text" xsi:type="string"><![CDATA[<script type="text/x-magento-init">{"*":{"jquery.bootstrap":{}}}</script>]]></argument>
            </arguments>
        </block>
    </referenceContainer>

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.