Create a custom in-panel widget

This tutorial walks you through the steps to create a basic custom widget. All required folders and files are included in the CustomWidgetTemplate folder so you can focus on writing the code.

To preview the final result of the custom widget, type http://[your host]/webappviewer/?config=sample-configs/config-demo.json in the browser. When the app starts, click the first icon highlighted in red circle as shown below.

Custom widget

  1. Rename the CustomWidgetTemplate folder.
  2. Go to the \\widgets\samplewidgets folder, make a copy of the CustomWidgetTemplate folder in the same directory, and rename it to MyWidget.

    MyWidget folder
  3. Set the widget baseClass name.
  4. Open Widget.js in the MyWidget folder and set the baseClass name as jimu-widget-mywidget.

    mywidget is the custom widget name.

    define(['dojo/_base/declare', 'jimu/BaseWidget'],
    function(declare, BaseWidget) {
      //To create a widget, you need to derive from BaseWidget.
      return declare([BaseWidget], {
        // Custom widget code goes here 
        baseClass: 'jimu-widget-mywidget'

    If you add other properties after the line of baseClass: 'jimu-widget-mywidget', don't forget to add a comma at the end of this line.

  5. Define the widget's UI.
  6. The widget's UI is defined by an HTML template. Open the Widget.html file, and copy and paste this. Save the file.
        <div>This is my widget.</div>
  7. Add the widget in the app config file.
  8. Open the config-demo.json file in the stemapp/sample-configs folder. Find widgetPool->widgets and add a new widget element like this. Save the file.
      "label": "MyWidget",
      "uri": "widgets/samplewidgets/MyWidget/Widget"
  9. Test the widget.
  10. Start the app through http://[your host name:3344]/webappviewer/?config=sample-configs/config-demo.json and click the icon. The widget appears like the following:

    Nonconfigurable MyWidget
  11. Make the widget configurable.
    1. Open the config.json file in the MyWidget folder.
    2. Add the following JSON-structured text to pass the config to the widget.
    3. Alter the HTML template to use the configuration defined in the above config file.

      Open the Widget.html file and replace with the following:

          <div>This is my widget.</div>
          <div>This is configurable.[${config.configText}]</div>
    4. Start the same app again and click the icon.

      Now the widget looks like the following. The ${config.configText} marker in the template is automatically substituted with the values in the config.json file.

      Configurable MyWidget
  12. Make it user-friendly.
  13. On the HTML page, a CSS file is used to lay out the page, making it user-friendly. Open the css/style.css file in the MyWidget folder and add the following code:

    .jimu-widget-mywidget div:first-child{
      color: red;

    Start the same app again and click the icon. The widget now resembles the following:

    http://[your host name:3344]/webappviewer/?config=sample-configs/config-demo.json
    Style the widget
  14. Access a map.
    1. Open the Widget.js file, uncomment out the startup function, and replace it with the following lines:

      The widget's map property is a type of from ArcGIS JavaScript API, which can be retrieved through in the startup function.

      startup: function() {
            this.mapIdNode.innerHTML = 'map id is:' +;
    2. Modify the Widget.html template to display the map ID property.
          <div>This is my widget</div>
          <div>This is configurable.[${config.configText}]</div>
          <div data-dojo-attach-point="mapIdNode"></div>
    3. Restart the app and click the icon. The widget now resembles the following:

      http://[your host name:3344]/webappviewer/?config=sample-configs/config-demo.json

      Map id
    • Go to step 10 if you want to skip the localization of the widget.
  15. Add i18n support.

    Currently, the widget contains two English strings: "This is my widget" and "This is configurable". Using the Chinese language as an example, to internationalize the UI, the following steps are needed:

    1. Open the nls/strings.js file in MyWidget folder.

      Replace the content with the following lines:

              label1: "This is my widget.",
              label2: "This is configurable."
          "zh-cn": true    
    2. Create a subfolder named zh-cn under the nls folder.
      zh-cn folder
    3. Copy the nls/strings.js file in the zh-cn folder.
    4. Open the zh-cn/strings.js file and replace the content with the following lines. Save the file.
          label1 : "我的widget。",
          label2 : "这里可以配置。"
    5. Open the Widget.html file and replace the hard-coded English strings with markers. Save the file.
          <div data-dojo-attach-point="mapIdNode"></div>
    6. Reload the app, change the browser's locale configuration to view the changes.
      http://[your host name]:3344/webappviewer/?config=sample-configs/config-demo.json
  16. Deploy the widget.
    1. Open the manifest.json file in the MyWidget folder and change the properties accordingly, such as widget type, name, locale, and so on. See Widget manifest.
    2. Copy the MyWidget folder into the \stemapp\widgets folder.
    3. Restart node.js and go to http://[your host name:3344]/webappbuilder. You will see MyWidget in the widget pool when you click Click here to add widget in the builder.

    The custom widget should always deploy to the stemapp\widgets folder.