20 Mar 24
It is always a challenge, both at the design and development level, to customize or theme web applications, especially when there are a variety of brand identities and service resellers involved.
As a front-end solutions architect, my job is to plan, execute and provide solutions that are simple and do not add unnecessary complexity at a technical level. I seek, as far as possible, to make the use easier for both the user and the client.
To do this, we always apply our KISS (Keep It Simple Stupid) methodology ;), seeking that these solutions fill the gap they are intended to solve and/or improve performance if they replace an existing functionality or architecture and, above all, that they are usable.
The need for each company or reseller of our service to be able to identify the product with its brand posed a challenge for our team: finding the most efficient way to offer real-time customization.
At first glance, to cover this requirement, environments had to be duplicated, styles, assets and code dependent on the brand image itself had to be established, so that when the static compilation was carried out, each reseller could obtain their personalized space.
We explored several ideas to address this use case, but each proposed solution seemed difficult to maintain in the long term and generated more needs and tasks than we were looking for. Therefore, we discarded them and continued looking for an optimal solution.
So, we immersed into the documentation, ran proofs of concept, and allowed ourselves moments of reflection to clear our minds in the form of walks which are known to help us think more clearly. And indeed, they seem to work; the results speak for themselves.
The idea arose in the form of a question, why not create a brand image simply by segmenting by URL in real time based on a configuration file? The result was the creation of a small ecosystem of tools, which, well communicated and organized, allow us to do just that.
Initially we controlled that each visit to a web app URL corresponded to a specific domain/subdomain. Later, by implementing a series of route middlewares in our router (vue-router), we saw that this was a common occurrence. Therefore, we moved this functionality from our vue entry point (APP, main, etc.) to a theme and customization control middleware that we integrated into our pipeline of middlewares for route access control.
For dynamic loading we had to solve the problem that stylus (we could have used scss or sass too) and CSS do not allow color changing at runtime when loaded via file. In other words, we cannot write the variables dynamically. For example, if we have color variables like $primary, $secondary, etc… (just to mention a few and there are more, since it is possible to set spacing, shading, fonts and a thousand other things), this will cause that during the execution of our build with webpack (or the bundler we use), the styles are generated based on these variables only the first time, without the ability to change them in real time.
The solution we found is to set those variables in our CSS with a default and then, thanks to our utility library, we can store and override those variables in the :root tag of our tag.
An example of defaults and how they could be used to allow dynamic loading and changing of pre-defined styles in our root element:
You can read more about CSS custom properties at https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties
Once we have identified from which domain or URL they are visiting us and we have the variables in our CSS, the next step is to load the different style variables from a configuration file. To do this, we have created a JSON file that contains the URL and all the available customization options. In this way, we only need to consult this file to get the variables and load them into our HTML.
At this point it is crucial to add a performance layer, so we need to persist data. To achieve this, we can use tools like Vuex, Pinia, or even the browser’s LocalStorage
object. This persistence allows us to store the theme data if we don’t have it yet, so that next time we can validate the absence of changes in the theme or domain during the loading of the visited URL. Thanks to this, changing colors, images or other elements is extremely easy.
Pros vs cons
Pros:
Cons:
You can see how to manage your variables in a modular way here: https://css-tricks.com/breaking-css-custom-properties-out-of-root-might-be-a-good-idea
In our app and during the build of the same we establish default values for the style variables. By minifying and compressing and/or hashing files, the client/reseller front end will have these default values and the variables that later, appropriately encoded, allow modifications to be made according to the criteria we establish.
In our case, these criteria are based on the URL or domain/subdomain, but they could also be a selector in the interface with communication and persistence through a REST API, for example.
In this way we ensure that during the execution of the application, each user can enjoy a customization adapted to their individual needs.
Author: Antonio Gregorio Bacete Ramírez
Antonio Bacete Ramírez is a Frontend Solutions Architect at Transparent Edge. He is particularly interested in innovation and front-end usability applied to each project he develops. He has advanced knowledge in other languages and frameworks and is one of the great references for the tech team.