At Kingmakers, I helped lead the architectural work required to scale a front-end application that originally served a single brand into a solution capable of supporting multiple brands and multiple languages, while maintaining one shared codebase inside a monorepo.
The brands involved were:
- betking.com
- supersportbet.com
The objective was clear:
Support multiple brands and multiple languages while keeping a single front-end codebase.
This article explains the approach I helped design, the architectural decisions we made, and how we safely rolled the solution out to production.
The Starting Point
When I joined the team working on this part of the solution, the setup was simple:
- one front-end codebase
- one brand
- one consistent user experience
Because of this simplicity, development was fast and predictable.
However, the business required us to expand the solution so that:
- 1the same front-end would support multiple brands
- 2each brand could support multiple languages and locales
- 3we should avoid duplicating front-end applications
This meant we needed to evolve the architecture without compromising maintainability.
Aligning with Business Requirements
Before implementing a solution, I worked with stakeholders to understand:
- which brands we needed to support
- which countries and languages each brand would operate in
This early alignment allowed me and the team to design a solution that would scale properly instead of solving only the immediate requirement.
One of the most important conclusions from this discovery phase was:
Brand and language should not be solved using the same mechanism.
They have different operational risks and therefore required different approaches.
My Key Architectural Decision: Separate Brand and Locale
The architecture I helped introduce separated brand configuration from language configuration.
Brand
Brand needed to be strict and deterministic.
Serving the wrong branding would immediately damage user trust.
Locale
Locale needed to be dynamic and flexible, with safe fallbacks when content was unavailable.
This separation allowed us to build a solution that was both safe and scalable.
Implementing Multi-Brand Support
To support multiple brands from the same codebase, I helped introduce a theme-based architecture.
The idea was simple:
- keep one front-end codebase
- move all styling and branding into themes
- select the theme through an environment variable
This meant that at build time, the correct theme would be compiled into the application.
As a result we produced two deployments from the same monorepo:
- one deployment for betking.com
- one deployment for supersportbet.com
Why this approach was important
I deliberately chose build-time brand configuration because brand mistakes are highly visible.
If the wrong brand theme appears even briefly, it can undermine customer trust.
By resolving branding at build time, we removed that risk entirely.
Implementing Multi-Language Support
Language requirements were different from branding.
Languages need flexibility because the same brand may operate in many countries.
For this reason I helped design the solution so that locale is resolved at runtime.
Locale from the URL
Locale is derived from the URL path.
For example:
/en-NG
/frThe application reads the locale from the path and loads the appropriate translations.
Fallback Strategy
If a locale is missing or unsupported, we fall back to English.
English was selected because it is widely understood in the markets where the solution operates.
This ensured the user experience always remained functional.
Introducing the Discrimination ID
As the solution expanded to support multiple brands, languages, and devices, I introduced a concept we called the Discrimination ID.
The Discrimination ID combines three pieces of runtime context:
- Brand
- Locale
- Device type (Web, iOS, Android)
This identifier became the single source of truth for request context.
Runtime Context Resolution
When a request enters the solution, the Discrimination ID is derived from three signals:
| Context | Source |
|---|---|
| Brand | Base URL (betking.com or supersportbet.com) |
| Locale | URL path |
| Device | Request headers / user agent |
These values are combined to form the Discrimination ID.
Simplifying Frontend–Backend Integration
One of the benefits of introducing the Discrimination ID was simplifying communication between the frontend and backend.
Without it, every API request would need to include parameters such as:
- brand
- locale
- device
Instead, the frontend can call the same endpoint and the backend automatically understands the context using the Discrimination ID.
Example: Registration Form
A good example is the registration flow.
When the frontend requests location data, such as available cities, the backend uses the Discrimination ID to determine:
- which market rules apply
- which cities should be suggested
- which defaults should be used
This significantly reduced the complexity of frontend requests and made backend behaviour easier to manage.
Analytics Improvements
The Discrimination ID also improved analytics.
Because every event included the same context identifier, we could easily analyse metrics by:
- brand
- country or locale
- device type
For example we could quickly determine:
- registrations per brand
- registrations per country
- registration behaviour by device (Android, iOS, web)
Safely Migrating to the New Solution
The introduction of locale-based routing meant the new solution behaved differently from the original system.
The previous setup did not include locale in the URL.
To avoid disrupting users, I helped design a controlled rollout strategy.
Controlled Rollout with Cookie Gating
The new solution was deployed to production but only activated when a specific cookie was present.
Routing logic was implemented so that:
if cookie == true
route user to new locale-aware system
else
route user to existing systemThis allowed:
- developers
- QA engineers
to test the new solution in production using real data without exposing it to all users.
Gradual Production Rollout
Once the solution proved stable, we began gradually rolling it out.
The rollout process was:
- 1start with registration
- 2enable the solution for a percentage of users
- 3monitor successful registrations
- 4expand rollout to additional parts of the application
- 5eventually reach 100% traffic
This approach ensured a safe and controlled migration.
The Result
The final solution allowed Kingmakers to support:
- multiple brands
- multiple languages
- multiple device types
—all from a single front-end monorepo.
Key benefits included:
- one shared codebase
- deterministic brand configuration
- flexible runtime localisation
- simplified frontend–backend integration
- improved analytics segmentation
- safe production rollout
Reflection
Helping design and deliver this solution was particularly rewarding because it combined:
- architectural design
- collaboration with business stakeholders
- runtime context modelling
- production rollout strategy
Most importantly, it created a foundation that allows Kingmakers to expand into new markets while maintaining a clean and maintainable front-end architecture.
