How to expose OutSystems UI as widgets

Sezen de Bruijn
ITNEXT
Published in
9 min readJun 16, 2023

--

We have a lot of customers who are looking to include OutSystems UI elements into portals or applications that are built in other technology stacks.

The goal is usually to include these UI elements as functional widgets, or micro-frontend components within a broader website or portal. That way they are able to offer these new products within their normal customer touchpoints.

Why doing this is a bad idea

(And you are a dunce for reading this article)

In general I would caution against integration on UI level als it inherently leads to worse Performance, worse UX and a solution that is less maintainable.

This is inherent to the approach and will happen regardless of the technological implementation because of an underlying sense of ownership.
When you break up a screen in little pieces that are maintained by seperate groups of people you will agree on standardized interfaces between the systems, so that they can all coexist in the same context, but you will by definition be less coordinated across the inner workings of the pieces.

This means that verious components will be loading the same javascript/css libraries, because they cannot assume that these libraries will be there. This leads to a worse performance.
It will be pretty feasible for everyone to have the same styling, leading to an uniform UI, but the userflows will be broken up in pieces, leading to a less coherent UX.
Finally having these isolated technologies coexisting in the same context, means we are upping both the level of integration on the UI side, as creating a lot of duplication between elements. If we find a security issue with a javascript library we now need to update multiple components, across many different teams. This makes it a less maintenable solution in my opinion, with a more complex architecture and a lower level of security.

So if you’d ask me I’d typically recommend you to make one team the owner of the UI, and have the other teams provide the necessary information through API’s.

Why people do it anyway

(And you are actually very smart for reading this article)

Its once again down to ownership. Conway’s law states that the structure of your software will mirror that of your organization.

In organizations where the internal structure looks like isolated teams having complete responsibilty for their own products (including launch dates and online promotion) a widget structure can actually be an organizational necessity.

You cannot expect the team to be responsible from start to end without giving them comple autonomy. That includes being able to go live with user interfaces without the help of any other teams.
Of course, you might suggest to give these teams completely independent websites, but most companies like to present an unified UI to their customers.

For example, in industries like Insurance, large companies often have a lot of distinct technology stacks that service various departments. These stacks come with their own User Interface technologies, which are typically expected to be integrated within the general portals towards customers, employees and partners.

In these scenario’s, some form of UI integration seems to be inevitable. But to be fair, widgets are not the only UI integration scenario.

An alternative to consider

Integrating through the menu. Here you basically build your screen in OutSystems as usual, but take particular care to match the UI of the portal that will be hosting the screen. The menu then links to this page, and with the right SSL certificates not even the URL gives away that you’ve navigated to a completely different technology stack. This is, in my opinion, the best approach for full screen integrations.
You avoid the whole performance degradation, and you can create full UX flows around your product. It also really reduces the complexity of the integration and improves the maintenability.

Loosely-coupled architecture in UI integration

If you do need to integrate OutSystems as widgets in the UI however, the technical approach is runtime integration. This basically means that your OutSystems UI components will stay on the OutSystems platform, and the portal will render those element within their interface.

The big benefit of runtime integration is that it allows the team that maintains the widget(s) to bring new versions of the widgets to production independently.
Runtime integration is a loosely coupled setup, which enables independent lifecycles and therefore increased agility.
This contrasts against compilation-time integration (using the web component technology), where the code is compiled into the application.

The runtime integration approach uses the iframe tag, and iframes have a bad rap, for some legitimate and some less legitimate reasons.

Why your frontend developer just visibly winced when you said the word iframe

Here are some objections people have against iframes. I’ll try to indicate where these objections come from, whether they accurate and whether they can be solved.

  • Outdated technology: iframes exist since the 90’s and have been maturing for ages. This means that many of the more experienced devs have experienced iframes in a period before certain javascript options were available, which we use to fix a lot of issues nowadays.
  • Security headers: we typically don’t want other people to add their own content on our websites as they might illicitely capture information, and we also don’t want pieces of our website embedded in a malificent website, as it might help legitimize a bad actor. So security headers where invented to limit this type of embedding. For iframes you need to add additional addresses to be allowed by these headers. Luckily you have full control over both technologies in our scenario, so that is not actually dangerous.
  • Bad UI: this perceptions stems partially from the fact that people use iframes a lot to implement third party technologies and have therefore no ability to adjust the widget. This creates a bad look-and-feel. Luckily, with OutSystems you can ensure that your widget uses the same styling and UI implementation methods, reducing that problem significantly.
  • Bad UX: as we discussed above there are some unavoidable UX limitations when you use a widget strategy. But beyond that there are some technical issues that people have come across in the past, that I will address here:
  • Scaling issues: when the screens get resized, iframes inside those screens can provide some weird behavior. This can be fixed with sufficient amounts of javascript on both sides (more about that later)
  • History/back button: if people navigate within an iframe this does not automatically get reflected in the portals history, meaning that if people use the browsers back button it will go to the place it was before people started to use the widget. This also can be fixed with javascript.
  • URL manipulation: because the iframe lives on its own url, when the user navigates within the iframe the portals url does not reflect that. This means that the user can’t copy the url and save it to return later, for example. This is, once again, completely fixable with javascript.
  • Accessibility: it’s important that everyone can access your websites, and some users will need to use tools like screenreaders and tabs to navigate your UI. For some reason the perception exists that iframes make this impossible. I’ve tried it out and my implementations that include iframes are perfectly navigatable using these tools, so I’m not sure where this perception comes from. Let me know if you do!

The points above here we want to address are the drawbacks of the runtime integration. By deliberately seperating the widget and the portal into their own contexts, you are required to explicitly communicate all events that might influence the other element.

We basically have the same problem as we have when we decide to pick a restaurant together with another person (vs eating alone), a lot more communication is required.

Luckily, we can use a tried-and-true method that I developed in my childhood: hiding the mess in the closet before mum enters the room!

Or in this case, hiding the iframe under a layer of javascript.

You have most definitely used an iframe before as its the technology used in most embed scenario’s. Google Maps to show where your offices are? Iframe! Want to show your Youtube video’s on your website? Iframe!
But even if you were the one who implemented it you might not know it, because they hid it under a layer javascript.
So lets embed like the best!

This requires accounting for the following underlying non-functional requirements:

  • Responsiveness of the widget (dynamic width & height, no scroll bars, resizing, allowing other items to display over it when required, etc.,)
  • Sharing context and information safely, for example when navigating inside the widget updating URL on browser. Or when logging in on the portal sharing the session context so that the widget can independently verify authentication
  • Possibility for analytics and tracing IAM and SSO;

Accounting for these non-functionals is what makes a widget strategy based on runtime integration difficult to execute.

Sending the widget and portal to couples counseling

If we are serious about our widget strategy we need start setting up our infrastructure first.

First we need to establish pathways of communication between the widget and the portal. We establish javascript event listeners on both sides that basically wait for events that the partner might need to know about and shares that information. This way the portal will let the widget know that we are resizing, and the widget will let the portal know that the user is navigating.

That is where the widget accelerator comes in.

What is the Widget accelerator?

A Forge component that provides you with the assets (and example implementation) of the three most important elements for a widget strategy:

  1. Everything you need to make the OutSystems Widgets
  2. Everything you need to embed the Widgets in your portal
  3. Everything you need to enable underwater authentication towards an IDP

So how do I build a Widget?

Building a Widget with this component is relatively simple.

  1. After installing the component you have a screentemplate available called “WidgetToExpose.” Select this screen template.

2. Create your screen and start building the widget just like you normally would.

3. Your use case might require custom events. If you want to capture custom events open the “ListenerEvent” action, and include an if-statement that checks if the message that comes in is related to your event.

4. Publish

5. Share the URL of your widget with the portal team

So what is the portal team supposed to do?

On the portal side you need to take the following steps to embed the widget:

  1. Create an empty div, with a style class. You are going to use this style class to identify the div, it does not need any actual styling assigned to it. In our example we’ll give it the styling class ‘OS’.
  2. Include the OSApps script. (You can find it in the WidgetAccelerator Demo Component.)
  3. Create a javascript action that runs onReady, which runs something along the lines the following javascript snippet:

function myListener(event) {

if(event.data.Event === ‘Navigate’){
history.pushState(null, ‘’, ‘Screen3?OS=’ + event.data.Content);
}}
window.Apps = new OSApps(myListener);
window.Apps.initApp(‘div.OS’, ‘widgetid’, “https://”+ $parameters.environmentDomain +”/WidgetAccelerator_Demo/AnonymousScreen?OS=”+ $parameters.ExtraURL,

{hideBorder: true, autoResize: true})

Is it really that easy?

Of course not. Here is some the added complexity that you might encounter:

  1. More advanced implementation scenario’s often also have a CMS system in the middle
  2. You likely will run into some security headers at both sides of the equation
  3. You will want to take care that CSS styling on the OutSystems side matches the styling on the portal site

Luckily the component comes with some handy documentation that tells you exactly how to deal with these things as well.

Too Long Didn’t Read:

  1. This is a bad idea from a technical perspective, don’t do it
  2. This might be a good idea from an organizational perspective (so you might have to do it anyway)
  3. OutSystems uses iframes in these scenario’s
  4. So if you have to do it, hide all the mess under a lot of javascript.

--

--

Low-Code Solution Architect ★ helping you build IT Fast, Right and for the Future ★ Let’s just have some fun :-)