Technical Implementation
How you go about implementing a white-label solution can be vastly different from project to project. At Dwarf, we’ve experimented with different implementation details to end up with the following structure:
The idea is to have a single repository as your “white-label base”, or “parent repo”, with all the code you want to be shared among the individual sites. Any code changes you make here should be applicable to every site, and deploying the changes just requires a pull from one of the “children” sites.
To enable each site to differentiate itself, it uses configuration files to control stuff like where the data is coming from and managing unique ID’s to 3rd party services.
We also write the code to make heavy use of CSS variables for all styling choices. This allows us to use a single configuration styling file to override the entire design system, giving each site its own color scheme, fonts, spacing scales, etc.
As mentioned earlier, it’s likely that your websites won’t always stay perfectly in sync (functionality-wise). Changing requirements or new business opportunities can easily mean that updates are necessary to a specific site. But how do you go about implementing this? We only want to make changes in the base when all the sites can benefit from it, so we need a solution where the files are stored in the individual site repos. And since a site should always be able to get updates from the base, we can’t just modify the base files in each site repo all willy-nilly.
That’s why we decided to use the “convention over configuration” paradigm. Each individual site can choose to “opt-out” of the base on a per-file basis, simply by creating a new file with the same name in its own “custom” folder. This allows a site to essentially “override” individual files or components and implement their own template and logic when necessary, while still keeping all other files in sync with the base to receive updates periodically.
This pattern turns out to be extremely powerful, and we accomplish it using a specific module for NuxtJS, our framework of choice for all our white-label frontends.
Tradeoffs
As with any software solution, it’s not only sunshine and rainbows. The white-label architecture does introduce some additional complexity:
- “Opting out” of a file effectively means you’re not getting base updates to that file. So any changes in the base will have to be added manually to the override
- The mental model required is quite different from building a traditional website, as you always have to think in abstractions when developing
- Merge conflicts can arise if a site has modified base-files (instead of overriding) and then tries to pull base updates
- A bigger up-front production cost, as the initial white-label base will need extra care during development
- When making changes in the base repo, you need to make sure that all sites will work when pulling the updates
Some of these issues can be lessened with good communication, a solid process, and automated testing. But it’s always harder to maintain multiple websites than a single one, especially when they begin branching off and adding custom functionality.
Conclusion
One question remains: Should you choose a white-label architecture for your next project?
As we’ve explored in both parts of the article, there are many advantages to a white-label approach if your needs require it. It’s a great pattern when the advantages of a shared codebase, individual deploys, and the ability to rapidly launch multiple sites outweigh the tradeoffs - like in the provided examples. And from a technical point of view, it’s hard to beat a white-label solution in terms of maintainability, production speed, and large-scale advantages.
So if you’re in the process of developing multiple websites simultaneously, that share a lot of the same functionality, while still remaining independent and appealing to different target groups, white-label might be the way to go.
Let us know, and we’ll help you decide if a white-label solution makes sense for your project, and how you can go about implementing it optimally!
Written by
Mads Brodt Nielsen, Frontend Developer at Dwarf