Create a Custom Module

Important:

This example applies to customizations of the Kilimanjaro release of SCA or earlier. If you are implementing the Aconcagua Release of SCA or later, the best practice is to use themes and extensions to customize your site unless your customizations require access to objects not available using the Extensibility API.

SuiteCommerce Advanced (SCA) is designed so that you can extend it by creating new modules to add functionality specific to your website. When creating a new module, be aware of the following notes and requirements:

To add a custom module:

  1. Create a custom module directory within your custom directory with the format of ModuleName@version.

    Examples:

    • If implementing 2020.1 and later, create this directory in the extensions directory. For example: SC_20.1/extensions/MyCustomModule@1.0.0.

    • If implementing 2019.2, create this directory in the extensions directory. For example: SC_19.2_Live/extensions/MyCustomModule@1.0.0.

    • If implementing 2019.1 and earlier, create this directory in the Modules/extensions directory. For example: Modules/extensions/MyCustomModule@1.0.0.

    Important:

    You cannot use existing module names, even when those modules reside in different folders.

  2. Create the subdirectories within the module.

    The exact subdirectory structure depends on the requirements of your module and your implementation of SCA. You should use the same directory structure as existing application modules. Typically, you will need JavaScript, Sass, SuiteScript, and Templates subdirectories.

  3. Create the necessary files for your module.

    This is where all of your module’s logic is contained. These files are either JavaScript (.js) or TypeScript (.ts), depending on your implementation of SCA. At a minimum, you will need something like the following:

    Note:

    This procedure does not include examples of backend models or services files which are often necessary for backend integration with NetSuite.

    • Entry point – this file acts as an entry point to the module and must return an object containing the mountToApp property that receives the application as a parameter.

      JavaScript example:

                          //MyNewModule.js
      define('MyNewModule'
      ,   [
            'MyNewModule.Router'
         ]
      ,   function (
            Router
         )
      {
         'use strict';
      
         return   {
            mountToApp: function (application)
            {
               // Initializes the router
               return new Router(application);
            }
         };
      }); 
      
                        

      TypeScript example:

                          ///<amd-module name = "MyNewModule"/>
      
      import Router = require('./Router');
      
      export function mountToApp(application)
            {
               new Router(application);
         } 
      
                        
    • Router – if you are on SuiteCommerce 2019.1 or later, use extensions or a page type component. If you are on SuiteCommerce 2018.2 or earlier, this JavaScript file extends the Backbone router to map URL patterns to the views defined within the module.

                          //MyNewModule.Router.js
      define('MyNewModule.Router'
      ,   [   
               'MyNewModule.View'
            ,   'Backbone'
         ]
      ,   function (
               MyNewModuleView
            ,   Backbone
         )
      {
         'use strict';
      
         //@class Address.Router @extend Backbone.Router
         return Backbone.Router.extend({
      
            routes: {
               'my-new-module': 'MyNewModuleRouter'
            }
      
         ,   initialize: function (application)
            {
               this.application = application;
            }
      
            // list myNewRouter output
          ,   MyNewModuleRouter: function ()
            {
                 var view = new MyNewModuleView({
                    application: this.application
                 })
                 view.showContent();
              }
         });
      }); 
      
                        
    • View – this view is called from the router. Often, a view contains a getContext function that describes all of the variables that are passed from the view to the template.

      JavaScript example:

                          //MyNewModule.View.js
      define(
         'MyNewModule.View'
      ,   [
            'my_new_module.tpl'
         ,   'Backbone'
         ,   'jQuery'
         ]
      ,   function (
            MyNewModuleTemplate
         ,   Backbone
         ,   jQuery
         )
      {
         'use strict';
      
         //@class Address.List.View List profile's addresses @extend Backbone.View
         return Backbone.View.extend({
      
            template: MyNewModuleTemplate
      
         ,   events: {
               'click [data-action="test"]': 'testAction'
            }
      
         ,   testAction: function ()
            {
               alert("This is a test action")
            }
      
         ,   getContext: function ()
            {
               return {
                  //@property {String} myNewModuleContextVar
                  myNewModuleContextVar: 'myVariable'
               };
            }
         });
      }); 
      
                        

      TypeScript example:

                          /// <amd-module name="MyNewModule.View"/>
      
      import my_new_module.tpl = require('.//../my_new_module.tpl');
      import Backbone = require('../../../Commons/Utilities/JavaScript/backbone.custom');
      import jQuery = require('../../../Commons/Utilities/JavaScript/jQuery');
      
      //@class Address.List.View List profile's addresses @extend Backbone.View
      
      let BackboneViewExtend: any = Backbone.View.extend({
         
         template: MyNewModuleTemplate,
      
         events: {
            'click [data-action="test"]': 'testAction'
         },
      
         testAction: function ()
         {
            alert("This is a test action")
         },
      
         getContext: function ()
         {
            return {
               //@property {String} myNewModuleContextVar
               myNewModuleContextVar: 'myVariable'
            };
         }
      });
      
      export = BackboneViewExtend; 
      
                        
    • Template – this file contains the markup used in combination with the views. Note that the SCA implementation leverages the Handlebars templating process.

                          <h2>This is my template file for my new module. It takes variables, {{myNewModuleContextVar}}, passed from the View.</h2> 
      
                        
      Important:

      Template file names must be unique. You cannot have duplicate template file names even when they belong to different modules.

  4. If your custom module contains any configurable properties, you must include a Configuration subdirectory and place your Configuration Modifications within it. See Modify JSON Configuration Files for details.

    Note:

    This step only applies to Vinson implementations of SCA and later.

  5. Create a new ns.package.json file within the new custom module’s directory.

    • If implementing 2020.1 and later, consider this example: SC_20.1/extensions/MyCustomModule@1.0.0/ns.package.json

    • If implementing 2019.2, consider this example: SC_19.2_Live/extensions/MyCustomModule@1.0.0/ns.package.json

    • If implementing 2019.1 and earlier, consider this example: Modules/extensions/MyCustomModule@1.0.0/ns.package.json

    This file must contain entries for all of the directories required by the module. Use the following one of the following examples as a template.

    This file must contain entries for all of the directories required by the module. This file is either JavaScript (.js) or TypeScript (.ts), depending on your implementation of SCA.

    JavaScript example:

                    {
       "gulp": {
          "javascript": [
             "JavaScript/*.js"
          ]
       ,   "templates": [
             "Templates/*.tpl"
          ]
       ,   "ssp-libraries": [
             "SuiteScript/*.js"
          ]
       ,   "services.new": [
             "SuiteScript/*.Service.ss"
          ]
       ,   "sass": [
             "Sass/**/*.scss"
          ]
       }
    } 
    
                  

    TypeScript example:

                    {
       "gulp": {
          "javascript": [
             "JavaScript/*.js",
             "JavaScript/*.ts"
          ]
       ,   "templates": [
             "Templates/*.tpl"
          ]
       ,   "ssp-libraries": [
             "SuiteScript/*.js"
          ]
       ,   "services.new": [
             "SuiteScript/*.Service.ss"
          ]
       ,   "sass": [
             "Sass/**/*.scss"
          ]
       }
    } 
    
                  

    For Vinson implementations of SCA and later, you must also include the following lines within the gulp object of the ns.package.json file:

                    , "configuration": [
        "Configuration/*.json"
      ] 
    
                  
  6. Update the distro.json file.

    • If implementing 2019.2 and later, this file is in the Advanced directory. Examples: SC_20.1/Advanced/distro.json, SC_19.2_Live/Advanced/distro.json.

    • If implementing 2019.1 and earlier, this file is in the root directory of the SCA source code.

    Update this file with the following two changes:

    • Add an entry for the new module in the modules object.

      • Example if implementing 2019.2 and later:

                                {
            "name": "SuiteCommerce Advanced",
            "version": "2.0",
            "modules": {
                "../extensions/myNewModule": 1.0.0",
                "../Commons/Address",
                       "../AjaxRequestKiller",
                       "../Commons/ApplicationSkeleton",
              ...
        } 
        
                              
      • Example if implementing 2019.1 and earlier:

                                {
            "name": "SuiteCommerce Advanced 1.0.0",
            "version": "1.0.0",
            "modules": {
                "suitecommerce/Account": "1.0.0",
                "extensions/myNewModule": "1.0.0",
                "suitecommerce/AjaxRequestsKiller": "1.0.0",
                "suitecommerce/ApplicationSkeleton": "1.0.0",
              ...
        } 
        
                              
    • Define any application dependencies in the javascript object.

      For example, if the module is required in the Shop Flow application, add the module to the SC.Shopping.Starter entrypoint.

                          "javascript": [
          {
              "entryPoint": "SC.Shopping.Starter",
              "exportFile": "shopping.js",
              "dependencies": [
                  "Backbone.View.Plugins",
                  "jQuery.html",
                  "ItemDetails",
                  "myNewModule",
              ...
                  "UrlHelper",
                  "CMSadapter"
                  ], 
      
                        
  7. View your changes.

    Important:

    If you are on SuiteCommerce 2019.2 or later, all TypeScript (.ts) files are compiled to JavaScript (.js) files when executing the gulp local and gulp deploy commands.

    After creating your new module, you can test it by viewing your changes in the application. If you are running a local server, you caen view your changes by reloading your website. See Test SCA Customizations on a Local Server for more information.

    If you are viewing your site in NetSuite, you can deploy your changes using the developer tools. See Deploy SCA Customizations to NetSuite for more information.

Related Topics

Example SCA Customizations
Modify JSON Configuration Files
Extend Frontend Configuration Files
Configure Facet Fields
Extend the Backend Configuration File
Add a Child View to a Composite View
Override a Template File
Extend a Sass File
Add a Sticky Button
Customizing the Loading Icon
Adding a Custom Web Font
Extending Font Awesome
Displaying Device-Specific Carousel Images

General Notices