Pluggable Widgets API

Last modified: November 1, 2024

Introduction

Mendix comes with a wide variety of Widgets, but sometimes your app requires a widget outside of this set. To support a more advanced UI pattern or create app-specific interactions, you will need to make your own pluggable widget. This documentation will help you achieve that in Studio Pro 10. See these links for other versions’ documentation:

Your new pluggable widget can be used while modeling pages alongside standard Mendix components. It can also be shared between multiple apps and distributed through the Marketplace.

You are in control of a pluggable widget’s appearance and behavior. Customize a pluggable widget by implementing a widget as a plain React component written in JavaScript or TypeScript. The component will be rendered in a Mendix app, and will be able to use APIs provided by Mendix to interact with that app.

Pluggable widgets, like core widgets, can have properties which a Mendix developer can (and sometimes must) configure every time the widget is used in Mendix Studio Pro. You can define these properties by making a widget definition XML file (for more information on widget definition XML files, see the Widget Definition XML File section below).

Pluggable widgets can also include a preview component for when they are previewed in Studio Pro’s Design mode.

For information on which libraries Mendix supports when developing pluggable widgets, see the Pluggable Widgets section of Mendix Client.

For information on how to update Pluggable Widgets Tools to a newer version, see Updating Pluggable Widgets Tools

Client Component

The essential part of a pluggable widget is its client component: a React component rendered inside the end-user’s app. Creating this component requires some basic React knowledge. Read React’s tutorial if you have not worked with React before. Note that if you are building a widget for native mobile apps, you should use React Native instead of React.

The client component is mainly focused on presentation and interaction with an end-user, while data fetching, validation, and updating are handled by the Mendix Platform. Mendix provides your component with APIs which follow a unidirectional data flow pattern, much like the Redux and Flux APIs. Mendix follows the “batteries included but removable” motto. You do not have to care about nuances if standard behavior suffices for you, but you can adjust behaviors when required.

A widget component is mounted and unmounted when a widget is shown or hidden — for example when a page is opened or due to conditional visibility. A component receives props which resemble properties described in its widget definition XML file. A prop’s key comes from the key attribute, and its value is based on the configuration of the property. Prop values are immutable, but the Mendix Platform re-renders the component passing new values when necessary.

A prop value is often not just a primitive value, but an object whose structure depends on the type of its widget’s property. A prop’s values can expose data, metadata, and associated actions — whatever is applicable for the property. Here is an example of one interface. It is a value for an action property, such as the type you would find in the On click property of an action button:

    export interface ActionValue {
        readonly canExecute: boolean;
        readonly isExecuting: boolean;
        execute(): void;
    }

The above interface could be used this way: a component uses a canExecute flag to decide whether it should be enabled, uses an isExecuting flag to show an inline progress indicator, and triggers execute() method in a reaction to user click. Normally, after execute() has been triggered, the component will be re-rendered with a new value that has the isExecuting flag set, and when an action, for example a microflow, completes, the component is re-rendered again without isExecuting.

Widget Package

A pluggable widget is distributed as single widget package file with an .mpk extension. This file should be placed in your app’s widgets directory. Mendix Studio Pro discovers all widgets in your app when you open your app, add a widget through the Marketplace, or click App > Synchronize App Directory.

Manually building a widget package can be difficult, so Mendix recommends you use scripts provided by the Mendix Pluggable Widget Generator. For more information on how to use a generator, see How To Build a Text Box Pluggable Widget: Part 1.

A widget package file is just a ZIP archive containing the following things:

  • A package.xml file describing the whole package
  • A widget definition XML file, preferably located in {widgetName}.xml where widgetName is the last part of widget ID
  • A client component of a widget located, for example, in com/mendix/widget/MyProgressCircle.js for a widget with the ID com.mendix.widget.MyProgressCircle
  • Optionally, a widget preview Studio Pro’s Design mode located in {widgetName}.editorPreview.js
  • Optionally, widget icons (which must be the PNG format):
    • {widgetName}.icon.png sets the widget icon inside the Studio Pro toolbox in list view (the ideal image size is 64x64 pixels, but other sizes will be resized to fit)
    • {widgetName}.icon.dark.png sets the dark-mode equivalent to {widgetName}.icon.png
    • {widgetName}.tile.png sets the tile image inside the Studio Pro toolbox in tile view (the ideal image size is 256x192 pixels, but other sizes will be resized to fit)
    • {widgetName}.tile.dark.png sets the dark-mode equivalent to {widgetName}.tile.png
  • Optionally, some widget-related resources, preferably located next to the file which contains the client component
    • Note that all CSS files you add (except the one located in the lib sub-directory) will automatically be loaded in an app via the widget

Naming your widget package file after the widgetName is best practice. Also, a widget package can include multiple widgets by putting several of the above items in the same widget package. However, creating such packages is not recommended.

The package.xml file has the following structure:

	<?xml version="1.0" encoding="utf-8" ?>
	<package xmlns="http://www.mendix.com/package/1.0/">
		<clientModule name="{packageName}" version="{packageVersion}" xmlns="http://www.mendix.com/clientModule/1.0/">
			<widgetFiles>
				<widgetFile path="{widgetName}.xml"/>
			</widgetFiles>
		</clientModule>
	</package>

Both packageName and packageVersion should be aligned with the app’s information in the Marketplace if you wish to publish the package. It is best practice to use the widget ID as a packageName.

Widget Definition XML File

The widget definition XML file is an essential part of a widget because it describes that widget’s basic information and capabilities, such as if that widget can function offline. This file also contains a defined list of properties configurable in the widget. If you use the Mendix Pluggable Widget Generator, the contents of this file will be scaffolded for you.

A simple widget XML file might look like this:

    <?xml version="1.0" encoding="utf-8" ?>
    <widget [attributes]>
        <name>{User friendly widget name}</name>
        <description>{User friendly short description}</description>
        <properties>
            [properties]
        </properties>
    </widget>

A widget XML file consists of three sections: widget attributes, widget description, and widget properties definition.

Widget Attributes

Here is an example of a widget’s attributes section:

    <widget
        id="com.mendix.widget.MyProgressCard"
        pluginWidget="true"
        offlineCapable="true"
        supportedPlatform="Web"
        [...]
    >

This section is generated based on options chosen while running the Mendix Pluggable Widget Generator. You will rarely need to modify it after it is generated. This sample widget features several widget attributes:

  • id — This the fully qualified name of the widget called widget ID. Using widget ID, the Mendix Platform distinguishes widgets from each other. Widget ID should never be changed after a widget is used in an app or is published in the Marketplace. Reverse domain-style names, as in example above, are recommended.
  • pluginWidget — This should always be set to true. This way, the Mendix Platform can distinguish between the newer pluggable widgets and the older custom widgets.
  • offlineCapable — This shows if a widget can work while an app is offline. For more information on offline apps, see the Offline-First guide. A widget that fetches information from a third-party API, for example a widget that fetches airline ticket prices, could not function without an internet connection. If a widget cannot work offline, Mendix Studio Pro will forbid its use on pages that must be available offline.
  • supportedPlatform — This shows the platforms a widget is compatible with. Web describes widgets that are only compatible with web and hybrid mobile apps. Native describes widgets that are compatible with native mobile apps.

Widget Description

The presentation of the widget in Studio Pro is determined by the first set of elements inside the widget tag. The order of these descriptive tags is important, and is demonstrated in the list below. Only the name and description tags are mandatory — the others are optional. The description can be omitted with a self-closing tag: <description />:

  • name — The display name of the widget.
  • description — A short written description of the widget.
  • studioProCategory — See Toolbox Category.
  • helpUrl — See Help Page.
  • icon — See Icon.
    <name>My Progress Card</name>
    <description>Displays my progress.</description>

In Mendix Studio Pro, the widget described above would look like this:

basic widget
basic progress card in structure mode

Toolbox Category

To provide more clarity for Studio Pro users you can specify a toolbox category for your widgets. When provided, it determines a toolbox category for a widget in Studio Pro. It is possible to specify existing built-in categories such as Data or Input as well as new arbitrary categories like Maps.

When an existing category is specified, then your widget is placed in it next to existing built-in widgets. When a new category is specified, then your widget placed in that new category.

A category can be provided through the studioProCategory tag:

   <studioProCategory>Open Street Maps</studioProCategory>

In the example above, a widget would be placed under Open Street Maps widgets in Studio Pro. Note that widgets is added automatically in the Studio Pro UI.

Help Page

You can provide additional help information to widget users by using a help page. If you do so, a widgets configuration screen will get a Help button, assigned to the F1 shortcut key, that opens a specified page. This button is positioned in the lower-left corner of the popup dialog:

basic widget

A URL of a help page can be provided through the helpUrl property after the description tag:

    <helpUrl>https://marketplace.mendix.com/link/component/105695/</helpUrl>

For more complex help pages you can link to a markdown page. For security reasons, URLs have the following restrictions:

  • Must use HTTPS protocol
  • Host name must end with .mendix.com or github.com
  • If host name is github.com the full URL must end with .md

Icon

The <icon> element accepts a base64 encoded image that is displayed as the widget icon in Studio Pro. The element is optional and can be omitted. When no icon is provided, Studio Pro will display a fallback icon.

<icon>PHN2Zy...9zdmc+</icon>

Widget Properties Definition

This section is represented by the properties tag in the widget XML file. It describes widget properties used in Studio Pro to configure the widget. Here is an example of a properties definition section for a widget which shows a progress card for a dashboard:

    <properties>
        <propertyGroup caption="General">
            <propertyGroup caption="Main">
                <property key="label" type="textTemplate">
                    <caption>Label</caption>
                    <description>Card label</description>
                </property>
                <property key="icon" type="icon" required="false">
                    <caption>Icon</caption>
                    <description>Card icon</description>
                </property>
                <property key="percentage" type="attribute">
                    <caption>Percentage</caption>
                    <description>Progress percentage</description>
                    <attributeTypes>
                        <attributeType name="Decimal"/>
                        <attributeType name="Integer"/>
                    </attributeTypes>
                </property>
            </propertyGroup>
            <propertyGroup caption="Action">
                <property key="showButton" type="boolean" defaultValue="false">
                    <caption>Show button</caption>
                    <description>Show button on the card</description>
                </property>
                <property key="buttonAction" type="action" required="false">
                    <caption>On click</caption>
                    <description>Action to be performed when button is clicked</description>
                </property>
                <systemProperty key="TabIndex"/>
            </propertyGroup>
        </propertyGroup>
        <propertyGroup caption="Visual">
            <propertyGroup caption="Progress bar">
                <property key="animateProgressBar" type="boolean" defaultValue="true">
                    <caption>Animate</caption>
                    <description>Show progress bar animation</description>
                </property>
                <property key="progressBarColor" type="expression" defaultValue="'red'">
                    <caption>Color</caption>
                    <description>Progress bar CSS color</description>
                    <returnType type="String" />
                </property>
            </propertyGroup>
        </propertyGroup>
    </properties>

Property Groups

Before examining properties themselves, it is useful to understand property groups. Property groups are formed by properties wrapped in a propertyGroup tag. Studio Pro uses the property groups to render how the widget configuration UI appears in Studio Pro. Grouping can be used to help the modeling developer understand the configuration of a more complex widget. It is best practice to both use property groups and group properties based on their purposes. The property groups from the code in Widget Properties Definition above forms the following structure:

    ├── General
    │   ├── Main
    │   │   ├── Label
    │   │   ├── Icon
    │   │   └── Percentage
    │   │
    │   └── Action
    │       ├── Show button
    │       ├── On click
    │       └── Tab index
    └── Visual
        └── Progress bar
            ├── Animate
            └── Color

This is how the property group structure is represented in Studio Pro:

edit progress general
edit progress visual
properties widget

When properties are shown in a dialog box, first-level groups (General and Visual) are represented as tabs. Second-level groups (Main, Action and Progress bar) are represented as boxes. When properties are shown in a pane, first-level groups are ignored and second-level groups are shown as categories.

Note that the Common and Appearance tabs are added to your widget configuration automatically. These tabs contain properties applicable to all widgets: Name, Class, Style, and Design Properties.

Widget Property

This section will explain the shape of the widget property. For more detailed information on widget properties, see Pluggable Widget Property Types. Every property tag in the Widget Properties Definition has a shape similar to this:

    <property key="cardName" type="textTemplate">
        <caption>Card name</caption>
        <description>Name of the card</description>
    </property>

Some properties can or must have more attributes or tags. This depends on the type property. The following elements should be present for every property:

  • key — This element is a property’s unique, single-word identifier. The key elements are used internally to identify properties, so they should never change after a widget is used in an app or is published in the Marketplace. A key element also identifies a property value when it is passed to a pluggable widget’s client component.
  • type — This element is a property’s type. The type element defines which values can be configured for a property, which UI is used in the Mendix Studio Pro, and what type of value a pluggable widget’s client component receives.
  • caption — This element is a short label identifying a property to a modeling developer. The first letter of a caption should be capitalized.
  • description — This element is a longer description of a property. A description should be capitalized and limited to one or two sentences.

Here is how a caption and description look in Studio Pro:

caption
description

Documents in this Section

Mendix offers the following APIs for pluggable widgets:

  • Property Types
  • A guide for understanding pluggable widgets’ property types in Mx10.

  • Client APIs
  • A guide for understanding the client APIs available to pluggable widgets in Mx10.

  • Preview Appearance APIs
  • A guide for understanding the APIs which influence pluggable widget preview appearances in Mx10.

  • Configuration Module API
  • A guide for understanding the configuration module API which influences the behavior of pluggable widgets in Mx10.

  • Mendix 9
  • Information on the Pluggable Widget API in Mx9.

  • Mendix 8
  • Information on Pluggable Widget API in Mx8.