This might interest you
Application themes help you define the look and feel of your app. In a simple scenario, you may have only one theme for your app, and that’s enough. But, in more complex scenarios, you may want to give your users the freedom to do some customization. Maybe you want to kick your app experience up a notch by adding dark mode or letting your user change the menu colors from green to red.
A quick search on your favorite search engine for “how to manage multiple themes for apps” will show you dozens of step-by-step tutorials on how to do it using Flutter. That’s definitely an option. But for this blog post, I’ll focus on OutSystems instead.
Whether you’re looking for an alternative platform that allows you to add and change app themes on-demand, or you’re an OutSystems user looking for the step-by-step tutorial you haven’t found on your Google search, this blog post is for you.
I’ll cover three different scenarios:
- How to add the same theme to multiple applications;
- How to add multiple themes to the same application;
- How to switch from theme to theme at runtime without impacting the functionality of your application.
This article is based on a recent Tech Talk, so for a more detailed demo, take a look at my session How to Manage Multiple Themes for Your Apps.
Managing One Theme Throughout Multiple Applications
Scenario 1: You have multiple applications and want to ensure they all follow corporate branding while promoting reusability and consistency.
For this first scenario, it’s important to understand how the OutSystems front-end architecture works.
In OutSystems, when you create an application from scratch, the platform generates it based on a template that will set up the app structure. In this new application, you’ll have the OutSystems UI being referenced allowing you to use all the functionalities it provides.
Quick note: in OutSystems, we use the term “application” to refer to the set of modules defined in Service Studio — the OutSystems development environment — that constitute the minimal deployment unit for LifeTime — the OutSystems console for managing all your environments, applications, IT users, security, and app lifecycle. You can learn more about OutSystems architecture in Application Architecture: Best Practices for Future-Proofing Your Apps.
Now, let's look at the scenario I first introduced: you want to add your corporate branding and promote visual consistency among your organization's several apps.
To do that, you need to set up the front-end architecture. This will basically create some isolation to promote reusability, consistency, and efficiency. Here’s how it’ll look like:
Let’s scale up this architecture and see how OutSystems promotes a reusable architecture that ensures your apps’ consistency. In the example below, you have three different uses of the front-end architecture:
- Business to Consumer Applications: These B2C apps are built on top of a particular theme, the B2C theme. On top of it, we have the Live Style Guide to test the visual assets and ensure they meet the brand requirements.
- Business to Business Applications: In these B2B apps, we’re implementing our corporate branding (corporate theme) and, on top of it, our B2B guidelines (B2B theme).
- Corporate Applications: Finally, the corporate applications are built on top of the corporate theme.
Looking at the application architecture, here’s how this front-end would translate into an actual application, using the example of a B2B application:
We have an end-user application that splits into four applications. So, at the bottom, we have the OutSystems UI and, on top, the corporate theme. This corporate theme includes the theme and the patterns and resources (example: images), where we’ll get the UI blocks that will be implemented in the app.
On top of the corporate theme module, we have the B2B theme, and on top of that the end-user application. Finally, we have the B2B Live Style Guide, a normal end-user app showcasing everything you've built in terms of the front-end, including the template to create new B2B apps.
This way, when you create a new end-user B2B app, you start it using the template you’ve built before and ensure consistency between different applications.
Managing Multiple Themes in One Application
Scenario 2: You have a SaaS app that requires different branding depending on the user/ organization logging in.
Two approaches allow you to change the look and feel of an app at runtime:
- CSS variables.
- Custom themes.
1. Managing Multiple Themes with CSS Variables
You started the application using a theme. Let’s say that application has a configuration screen that allows you to configure new colors. As soon as you define this configuration, you can save it as a stylesheet on the Configs module.
Then the app will fetch the URL where the stylesheet will be made available and cache the URL in a client variable. When your app gets this information and the change happens varies from use case to use case; it can happen when the user opens the application or after the user login, for example. It all depends on when you want it to happen.
After getting the URL, during the OnInitialize event handler of the screen layout, we load the CSS file — the stylesheet. By doing so, we’ll set the CSS variables according to the configuration we did in step one. To do so, we use a library to load the stylesheet.
Here’s how to do it:
By doing so, we’ll get a link, and the browser will download the stylesheet that was generated based on the CSS variables configurations, effectively applying them to your application.
Let’s look at it in greater detail: in step 1, when we’re saving our configuration into a stylesheet, we’re creating a text file and serving it as binary in the database. We’re also generating a GUID and saving it as a token to use later.
Then, in step 2, when the app gets the URL, it will be the REST endpoint that serves the stylesheet for download. The token will be used as the input parameter for the REST endpoint. So, in step 3, when we use the library to load the stylesheet, if there’s no change to the configuration, we can leverage the OutSystems built-in cache mechanisms on that REST endpoint so that even if we have lots of users, it won't result in new queries to the database.
However, if we change the configuration, the token will change and, as such, the REST endpoint will return the newly updated stylesheet.
When to Use This Approach
It depends on the changes you want to make. Suppose the changes correspond to OutSystems CSS variables. In that case, that's a great use case for this approach since the OutSystems UI already has many CSS variables, such as typography, colors, borders, and app settings.
2. Managing Multiple Themes with Custom Themes
For this approach, you have an application with a base theme, and you’ll use the back office to make the configurations of the app. In the first step, you’ll choose the custom theme to apply, according to a set of custom themes that we previously built with OutSystems.
That OutSystems theme will have the stylesheet, so we’ll be getting the custom theme URL and caching it in a client variable. Again, this will vary according to the use case. For example, if we want the custom theme to depend on the organization, we’ll need to know first who the user is and which organization he/she belongs to, to then adjust the colors to the organization.
Finally, we’ll load the stylesheet on the OnInitializeevent handler on the screen layout. In this final step, we’ll load this custom theme to the application using the same library.
Here's how to do it:
We'll do pretty much the same thing for this scenario as we did in the previous approach.
The difference is, we’re loading a stylesheet that was built with OutSystems in Service Studio. We can use the Theme Editor to build the themes and customize them using CSS. For that reason, the URL will be slightly different.
In step 2, when we fetch the URL, this URL will be built based on the theme’s module and the theme's name. Then we’ll add a question mark and the version of the theme’s module. We do this because, in step 3, the browser will use this URL to download the stylesheet when we load the theme. In addition to that, the browser will use its cache, so every time we publish an OutSystems theme, we need to change the URL so that the browser gets the new stylesheet.
When to Use This Approach
This approach should be used for more advanced scenarios, such as SaaS apps that require different branding per organization (different logo, different colors).
But you can also use it to address other scenarios like:
- Customizable product: when you have the base product and want to add some customization on top of it for a specific customer, like a new screen or functionality.
- Preferred user theme: when you want to give your users the freedom to choose the theme they want to use for themselves.
- Day/Night themes: when you want the app to switch between light and dark mode, based on the user’s local time.
Switching Themes Without Impacting App Functionality
Scenario 3: You want your application to change a theme in runtime without breaking the app.
The challenge with this scenario is that when you create OutSystems applications that reference themes, there’s a strong connection between themes and apps. This means that the applications that consume the same theme are strongly coupled. So, when you create a new end-user application, your theme module’s code will be compiled, and it will be included in the end-user application.
To overcome this challenge, you can use a couple of options to change a theme without impacting all your applications.
- CSS Variables.
- Custom Themes.
1. CSS Variables
There are two ways of setting the values of the CSS variables:
2. Custom Themes
The other option is through custom themes, and there are also two paths you can follow:
When to Use Each Approach
To help you define the right approach to use, I’ve compiled the pros and cons of each approach in the table below:
Put It Into Action
We’ve seen challenges, approaches, and options for how to manage multiple themes. But how can we actually do it? OutSystems offers two Forge components to simplify this process:
Gonçalo Santos is a Tech Expert Lead at OutSystems, with a long track record of experience driving the functional and technical vision of solutions from ideation to the hands of users. He gets his drive from continuously learning, practical problem solving through innovative solutions, and by helping others do the same. He has a dreamer’s mind stuck in a pragmatist’s body!See All Posts From this author