A Deeper Look at the New Widget Builder
The need for new widgets never dies. Layout possibilities are endless, new online business services could really use a widget with which to integrate, and buttons with cool animations are always welcome. Creating widgets at Duda is an ongoing, never-ending task, and demand always beats supply.
Today, building a new widget in Duda is not a trivial task. It requires writing a full, detailed spec, creating a pixel-perfect design, writing the code, reviewing the code, fixing bugs in the code, writing automation tests, QA, and, of course, ongoing maintenance.
Due to the high cost of building new widgets, and the knowledge that we were never going to build them all, we wanted to let users build their own.
How Moving to React Enabled Us Develop the Widget Builder
The nature of our code made it incredibly difficult for us to come up with an abstract concept of a ‘widget editor’ and what it contains. At the time, not all widget editors looked the same. Building a smart platform that could automatically create widget editors seemed like a fantasy.
This change didn’t only affect the way we code; it changed the entire development process. Instead of asking the product team for a pixel-perfect design of a widget editor, a developer only needs the list of components the editor uses. The components take care of the UI themselves.
Very quickly, we noticed that we no longer need to describe the UI using a folder of screenshots and mockups, but rather as a recipe of building blocks: the widget pieces.
Our next thought was, “If our product team can describe a widget only by its pieces – why not let our users do this as well?”
Suddenly, the idea of dynamic widget generation didn’t seem that farfetched. We identified three key goals we would need to achieve:
- Define a dependable model that describes a widget and its components.
- Create some kind of super generic widget editor that understands the model and puts the pieces together.
- Create a user-friendly interface that generates widget models that can later be passed to the editor (a.k.a The Widget Builder).
We ended up with a very well-structured representation of a widget. For rendering the widget editor, we keep the list of components. Each is coupled with its unique configuration, such as the field’s label, a unique identifier, a default value when initially adding a new widget, whether it’s mandatory or not, a list of options for dropdowns and radio buttons, and so on.
The generic widget uses the list of components and builds the internal concrete Duda components that are used everywhere else, resulting in very consistent behavior for both custom-made widgets and manually coded ones.
The Widget Builder
The main purpose of the Widget Builder is to provide a user-friendly interface for widget management. It has a dashboard where users can view and edit their widgets, it offers simple management tools for saving, publishing and restoring older versions, but its key goal is quite simple – maintain the widget model. Because the model is well structured and defined, this mission became fairly trivial.
Users can choose different design components that will be displayed in the design editor. These components allow the site owner to change the styling of the widget. All of Duda’s generic style components, including background, border, text and more, are available. These components manipulate the CSS of the widget and even allow setting custom selectors for refined styling capabilities.
Handlebars and Server-Side Rendering
An easy way to achieve this is by using HTML templates. To support this, the Widget Builder compiles the HTML code as a Handlebars template and injects it with values from the content components. This allows users to build dynamic HTML by using conditional statements, loops, and even pre-made Duda statements for common actions like links and button markup generation.
Since one of Duda’s top goals is to maximize site performance, we wanted to ensure that site speed is not affected by the use of Handlebars. That’s one of the main reasons why Duda renders widgets on the server side. Thanks to the heavy usage of cache for rendered pages, custom widgets are guaranteed to have optimized performance no matter how many widgets appear in a site, or how complex the template is.
How We Handle Widget Versioning
The Widget Builder is a fun and exciting project, and it has its fair share of challenges. One of the main challenges was identifying its target audience, and figuring out how to fulfill their needs. Traditionally, most new features are used by website designers. With the Widget Builder, things are a bit different, and it is mainly targeted at web developers. What we wanted is to build something that has the slick look and feel of the editor but is also powerful and flexible, like the IDEs that developers use.
We also tried to make the widget development lifecycle as close as possible to the development of any other feature. We developed advanced preview capabilities for easy coding, limited privacy settings for live testing, and smart versioning to support fixing bugs and code backup.
The versioning mechanism also provides a safe way for developers to introduce new functionalities to existing widgets without worrying about backward compatibility and breaking existing widgets. Every time a widget is republished, a new version of that widget is created. New widgets that are added to a site use the latest available widget, while existing widgets continue running in their original versions.
In the future, site owners will have the option to update widgets to their newest version in the editor, but at the moment, widgets are not updated automatically. This lets widget coders safely republish their widgets without fear of affecting running sites.
The Widget Builder is a major breakthrough here at Duda. Not only does it allow our users to significantly increase their service offerings, but it also helps us dramatically cut back on our own development time, as we no longer have to use traditional coding practices.
We have big plans for the Widget Builder going forward, and our backlog is packed with more existing features, including widget localization support, custom field validations, a proxy for performing server to server API calls, additional design and content components, managing widgets via API, enhancements to the code editors and much more.