The One Widget (Part 1)

05-27-2020 01:02 PM
Esri Contributor
3 0 1,190

A method of writing a widget that can be used both within Experience Builder or a regular React app.

When building a custom widget for Experience Builder, if your primary goal is to use the widget within Experience Builder, building it directly using the standard workflows is the best and quickest way to success.

But what if you need to create a widget that works in both a plain React app and within Experience Builder? With a little bit of extra work on top of the standard workflows, you can write a React component (widget) that can be included in both places!

One method to do this is:

  1. Use TSDX to create and develop a React Component.
  2. npm install the Component into the client folder of Experience Builder.
  3. Create a new custom Experience Builder widget. Within this widget, import and use the React Component you've created.

Pretty simple in theory. In practice, it can get a little complex, so I'll step through the details below.

1. Use TSDX to Create a React Component

TSDX is a "zero-config CLI that helps you develop, test, and publish modern TypeScript [React components] with ease." Create a new directory and in a terminal, run:

npx tsdx create my-widget cd my-widget npm start

Make sure you choose "react" for your template.

This will give you a folder structure of supporting files -- which is the infrastructure where you can build out your widget functionality as a React Component. Check out the TSDX documentation for more details on how to develop your component. TSDX comes with a "playground" React app under the example folder that you can use to see your component within the context of an example application during development. During development you will typically be running npm start in both the root directory (to build the widget) and also npm start within the example directory to run the app to see the component output.

Recommended Change - Default Export

By default, the template exports a React component named Thing. The first change I make is to export the component as the default export so importing is a bit more clean later on. So make these changes to my-widget\src\index.tsx and my-widget\example\index.tsx. Then after running npm start in both the root directory and the example directory, and browse to http://localhost:1234, you should be able to see your working component (just a single line of text):

React app

2. npm install the Component into Experience Builder

Now you have a React Component that is running in a React App (that's what's running at http://localhost:1234 above), so let's move on to showing our Component within Experience Builder.

First, install Experience Builder per the instructions here.

Then open a terminal and browse to the client directory in the Experience Builder unzipped files. Run npm install <PATH> where <PATH> is the local path to your React component. For example if you run the npm tsdx create ... command at C:\code\my-widget, you'll run npm install C:\code\my-widget.

(Tip: include --no-audit in the npm install... command to skip auditing all of Experience Builder's files)

3. Create an Experience Builder Widget

Now that it's installed, you can include this Component in any custom Experience Builder widgets. If you don't yet have a widget, you can copy the simple widget from client/sample-widgets/simple to client/your-extensions/widgets to start.

Within client\your-extensions\widgets\simple\src\runtime\widget.tsx, import your component by inserting an import statement near the top of the file:

import MyWidget from 'my-widget';‍‍‍‍‍‍

You can then use that component in the JSX near the bottom of the file. Replace the render() function with this:

render() {
  return (
    <div className="widget-demo jimu-widget m-2">

Remember to make sure npm start is running in the client directory so Experience Builder will re-build your widget and make it available.

After these changes, go into Experience Builder and add the Simple Widget to an Experience, and your component is now visible!

Experience Builder Custom Widget - single line text


Now you have a React Component that is working with the context of a React app and Experience Builder. This is a basic example - the next step is how to use widget configuration options and map modules. I'll dig into that in the next post - go here: 

About the Author
I am a geospatial developer working for Esri Professional Services.