duda
How to Use External Apps to Power Custom Widgets in Duda

Jason Hummel • Mar 31, 2020

Digital agencies, web professionals and SaaS companies all choose Duda to power their customers’ online presence for a variety of reasons, but one of the most common is undoubtedly the flexibility of the platform. Duda provides all kinds of fantastic native widgets for our customers to use right out of the box, but at the end of the day, what we really want is to empower our partners to build anything their customers need using whatever workflows are most comfortable to them. Sometimes this means using Duda’s custom widget builder, sometimes it means working with our REST API, and sometimes it means building an external app. Let’s explore that last one…

What is an external app?

As you (hopefully, or we should really talk to the marketing team) know, Duda offers a unique custom widget builder that allows developers to build entirely new widgets and integrate 3rd-party solutions directly inside Duda. When you build a custom widget in Duda, the JavaScript for that widget lives in a single function. This code must be maintained as part of the custom widget and can only be updated within the Duda widget builder. For most widgets, this works perfectly fine. However, this can pose challenges for a widget that require a significant amount of JavaScript. This is where you can use an external app to manage the logic of your custom widget.

External apps allow the behavior and logic of custom widgets to be developed and hosted outside the widget builder, while allowing any configuration required in the operation of the widget to still reside within the native Duda platform UI. This offers the best of both worlds — a first-class developer experience when creating the widget and a native Duda look-and-feel when your users add or configure the widget on their websites.

When should I use an external app instead of a normal custom widget?

Here are a few use cases in which it makes sense to use an external widget instead of simply building entirely inside the custom widget builder. They are not the only ones, but these should give you a good idea of how this tool can benefit your team.

  • The widget you’re building necessitates a large amount of JavaScript — more than could be comfortably programmed within the widget builder’s JavaScript panel.
  • You want to use your own IDEs, build process or external source control for the widget code. For instance, if you want to transpile TypeScript or ECMAScript to a JavaScript version available in all your target browsers or store the widget’s source in your company’s GitHub account.
  • You have an existing embeddable application you wish to re-purpose as a Duda widget.





Are there any trade-offs when using an external app to power a widget? 

Not really. The most important thing to remember when building external apps for Duda widgets is it puts more of the onus to maintain the widget on your team. 

Here are a few reasons why:

  • The JavaScript source code for your widget must be hosted by your organization outside of Duda, and you will be responsible for keeping the source available.
  • Building and deploying new versions of the source code are the responsibility of your organization, and can’t be initiated through the Duda editor.
  • The Duda editor will no longer hold backups of the previous versions of your code.





As the Peter Parker principle states, ‘with great power comes great responsibility.”

How do I implement an external app in the widget builder

The first step in setting up an external app with Duda is to execute the renderExternalApp method provided by the API object in the widget builder to point to the URL of your external app’s source. This is the only code required to be input into the JavaScript panel of the widget builder. 

Here is the JavaScript:

 

/* 

* Initialization function, called by the renderExternalApp function to lazy load your script

* @param {string} scriptSrc - Full URL of your built script

* @param {object=} container - DOM reference of the widget root

* @param {object=} props - configuration object supplied to your widget

* @param {object=} options - options needed when rendering a non-amd built widget

*/

api.scripts.renderExternalApp(<scriptSrc>, <container>, <props>, <options>)

To learn more, check out Building Custom Widgets at Duda University.

 

 Example of passing the element parameter from the widget builder function into the renderExternalApp method to be used by the external app.

Here is a brief explanation of each argument:

  • scriptSrc – The URL of your built widget src code. The source code must be hosted on a secure (https) domain. Complex applications should have their script built as a single file. This file will be lazy loaded into the site at runtime.
  • container – A reference to the DOM element into which the widget will be rendered. This reference is passed to you by the widget builder as the element parameter and you can simply pass it as an argument into the renderExternalApp method call.
  • props – An object of configuration data needed by your widget. This can be static values specified by the developer within the widget builder, global Duda data (such as siteId) provided by the data parameter in the widget builder, or specific configuration data provided by the data.config property entered by the user of the widget in the editor. See the developer documentation for a complete breakdown of available properties on the data object.
  • options – If your widget has not been built with an external tool such as Webpack, or was not built as amd you should provide the options argument with both name and amd properties: { amd: false, name: ‘my-widget-name’ }. See our developer documentation on external apps for more information.







Example passing configuration data to the external application.

Setting up the external app JavaScript

The basis of external apps are two functions for initialization and cleanup. The renderExternalApp method expects both of these functions to exist in your built source code. If you are using a build system utilizing modules don’t forget to export both these functions so they are available for execution. The functions will be passed an object containing the container, props and options specified in the widget builder.

Here is the JavaScript:

 

/* 

 * Initialization function, called by the renderExternalApp function to lazy load your script

 * @param {object} container - reference to DOM element into which the widget will be rendered

 * @param {object} props - props passed into script from the renderExternalApp method

 * @param {object} options - additional rendering options for non AMD built apps 

 */ 

    export function init ({ container, props, options }) {

      // initialization code

    }

    /* It's important to clean up your code as well,

     * Duda sites use Ajax page loading, and memory leaks

     * can occur if you continuously re-initialize applications

     * as the user navigates between pages

     */ 

    export function clean ({ container }) {

      // cleanup code

    }

Working with component-based frameworks

If you are using Vanilla JavaScript or utility libraries the above functions can be used as the entry and exit points of your application. It’s easy to just call additional functions as needed.

To go from pure functions to using components (like in React), you can simply use the container reference provided as a mounting point for your application.

Here is the JavaScript:

 

import React from 'react';

    import ReactDOM from 'react-dom';

    import App from './App';

    /* Using the DOM element passed to our script through the

     * renderExternalApp method as the mounting point of a

     * React application.

     */

    export function init ({ container, props }) {

      ReactDOM.render(<App {...props} />, container);

    }

    /* Using the same DOM reference to clean up our React

     * application when the widget is about to be removed

     * from the screen.

     */

    export function clean ({ container }) {

      React.DOM.unmountComponentAtNode(container);

    }

Working on your application outside of a Duda site 

You can use your own HTML scaffold and pass in your own DOM reference or element ID to view your application as you develop it without having to embed the widget into a Duda site.

Here is the HTML:

 

<!DOCTYPE html>

    <html lang="en">

      <head>

        <meta charset="utf-8" />              

        <title>React App</title>

      </head>

      <body>

        <div id="root"></div>

        <script src="/path/to/script.js" />   

      </body>

    </html>

 

And here is the JavaScript:

 

export function init({ containerId, container, props }) {

      const parent = container || document.getElementById(containerId);

      ReactDOM.render(<App {...props} />, parent);

    }

    /* Our init function will use the container prop when called

     * through Duda, or the containerId prop when working in dev

     */

    init({

      containerId: 'root',

      props: {

        testProp: 'External Apps are Awesome'

      }

    });

 

Important Note: You must remember to remove the manual call to init before building and deploying your code. If you are using Webpack or another build tool, use an environment flag so that the manual call to init only happens during development.

Here is the Javascript:

 

if (process.env.NODE_ENV === "development") {

      init({

        containerId: 'root',

        props: {

          testProp: 'External Apps are Awesome'

        }

      });

    }

 

Protips and useful hints

There are a few important points to remember when building external apps for Duda that will make life easier and more productive for your developers.

  • Build tools like Webpack should be configured to include assets like CSS inline. Otherwise, you’ll have to link to your external CSS within site templates.
  • Create-react-app doesn’t allow you to edit your Webpack configuration without ejecting, but you can use rescript to configure things exactly how you want.
  • If using create-react-app, you should use rescript to configure your output to use the UMD module format. Here is a sample git repo that includes a rescript configuration.





Though external apps are a relatively new technology for Duda, we see it as a big improvement to our platform and believe it will be a real game-changer, especially for our SaaS partners that provide more complex technologies to their customers. For more information on external app development and anything else that has to do with how Duda can take your online presence management to the next level, you can contact me via jason.hummel@duda.co. Documentation for building external apps can be found in Duda’s Developer Portal.

Entrepreneur's logo and How to design an eye-catching website that truly captures your audience.
By Itai Sadan 24 Apr, 2024
The rules governing a "well-designed website" are in constant flux. So getting insights into the latest web design trends for 2024 is crucial to captivate visitors and engage the right audience for your business.
The homepage for Duda.co
By Renana Dar 22 Apr, 2024
We sat out to redesign Duda's homepage using the most advanced capabilities of our own platform. See how we combined design, code, and advanced drag-and-drop capabilities to create a homepage like no other.
Three cards with a picture of a chair on them
By Shawn Davis 19 Apr, 2024
There exists a maximum number your customers are willing to pay, but finding that number is no easy task. Here’s everything your SaaS company needs to know about uncovering this elusive metric.
Show More

Latest Posts

Share by: