Mastering Multi-Brand Theming in Angular: Dynamic Themes for Every Brand

Ram Kumar

Ram Kumar

January 11, 20253 min read

Mastering Multi-Brand Theming in Angular: Dynamic Themes for Every Brand

In today's multi-brand landscape, it's common for applications to support multiple brands, each with its unique look and feel. Angular, with its powerful theming capabilities, makes it easy to create and manage themes for different brands. Whether you're using Angular Material or custom CSS, this guide will walk you through the process of creating and switching themes dynamically—even based on URL parameters!

Why Theming Matters

Theming allows you to:

  • Maintain brand consistency across different platforms.
  • Enhance user experience by providing a visually appealing interface.
  • Simplify customization for different clients or brands.

In this blog post, we'll explore how to create and manage themes for multiple brands in an Angular application, including how to dynamically load themes based on URL parameters.

Step 1: Set Up Angular Material (Optional)

If you're using Angular Material, it provides a robust theming system. To get started, install Angular Material:

ng add @angular/material

This will set up Angular Material and its theming system in your project.

Step 2: Define Theme Variables

Create separate SCSS files for each brand's theme. For example:

Brand 1 Theme

// src/styles/themes/_brand1.scss
@use '@angular/material' as mat;

$brand1-primary: mat.define-palette(mat.$indigo-palette);
$brand1-accent: mat.define-palette(mat.$pink-palette);
$brand1-warn: mat.define-palette(mat.$red-palette);

$brand1-theme: mat.define-light-theme((
  color: (
    primary: $brand1-primary,
    accent: $brand1-accent,
    warn: $brand1-warn,
  )
));

// Apply the theme
@include mat.all-component-themes($brand1-theme);

Brand 2 Theme

// src/styles/themes/_brand2.scss
@use '@angular/material' as mat;

$brand2-primary: mat.define-palette(mat.$blue-palette);
$brand2-accent: mat.define-palette(mat.$amber-palette);
$brand2-warn: mat.define-palette(mat.$deep-orange-palette);

$brand2-theme: mat.define-dark-theme((
  color: (
    primary: $brand2-primary,
    accent: $brand2-accent,
    warn: $brand2-warn,
  )
));

// Apply the theme
@include mat.all-component-themes($brand2-theme);

Step 3: Load Themes Dynamically

To switch between themes dynamically, you can use Angular's :host-context or a class-based approach.

Option 1: Using :host-context

Wrap your theme styles in :host-context:

// src/styles/themes/_brand1.scss
:host-context(.brand1) {
  @include mat.all-component-themes($brand1-theme);
}

// src/styles/themes/_brand2.scss
:host-context(.brand2) {
  @include mat.all-component-themes($brand2-theme);
}

Option 2: Using a Class-Based Approach

Add a class to the body element to switch themes:

// src/styles/themes/_brand1.scss
.brand1 {
  @include mat.all-component-themes($brand1-theme);
}

// src/styles/themes/_brand2.scss
.brand2 {
  @include mat.all-component-themes($brand2-theme);
}

Step 4: Switch Themes Based on URL Parameter

To dynamically load themes based on a URL parameter, we'll create a custom hook using Angular's ActivatedRoute and ThemeService.

Theme Service

First, create a ThemeService to manage the active theme:

// src/app/services/theme.service.ts
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class ThemeService {
  private activeTheme: string = 'brand1';

  setTheme(theme: string): void {
    this.activeTheme = theme;
    document.body.className = theme;
  }

  getTheme(): string {
    return this.activeTheme;
  }
}

Custom Hook to Get Brand from URL

Create a custom hook (or utility function) to extract the brand from the URL parameter:

// src/app/utils/get-brand-from-url.ts
import { ActivatedRoute } from '@angular/router';
import { ThemeService } from '../services/theme.service';

export function getBrandFromUrl(route: ActivatedRoute, themeService: ThemeService): void {
  route.queryParams.subscribe(params => {
    const brand = params['brand'] || 'brand1'; // Default to 'brand1' if no parameter is provided
    themeService.setTheme(brand);
  });
}

Use the Hook in Your Component

Inject the ActivatedRoute and ThemeService into your component and use the custom hook:

// src/app/app.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ThemeService } from './services/theme.service';
import { getBrandFromUrl } from './utils/get-brand-from-url';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {
  constructor(
    private route: ActivatedRoute,
    private themeService: ThemeService
  ) {}

  ngOnInit(): void {
    // Use the custom hook to get the brand from the URL
    getBrandFromUrl(this.route, this.themeService);
  }
}

Step 5: Include Themes in Your Application

Import the theme files in your global styles (styles.scss):

// src/styles/styles.scss
@import './themes/brand1';
@import './themes/brand2';

Step 6: Custom CSS Themes (Non-Material)

If you're not using Angular Material, you can define custom CSS variables for each brand:

// src/styles/themes/_brand1.scss
:root.brand1 {
  --primary-color: #3f51b5;
  --accent-color: #e91e63;
  --warn-color: #f44336;
}

// src/styles/themes/_brand2.scss
:root.brand2 {
  --primary-color: #2196f3;
  --accent-color: #ffc107;
  --warn-color: #ff5722;
}

Use these variables in your components:

// src/app/app.component.scss
button {
  background-color: var(--primary-color);
  color: white;
}

Step 7: Testing and Validation

  • Test your application with each theme to ensure consistency.
  • Use tools like Storybook to visualize components with different themes.

Example URL

To test your application, navigate to:

  • http://localhost:4200?brand=brand1 for Brand 1 theme.
  • http://localhost:4200?brand=brand2 for Brand 2 theme.

Conclusion

Creating themes for different brands in Angular is a powerful way to maintain brand consistency and enhance user experience. By leveraging Angular Material or custom CSS, you can easily define and switch themes dynamically—even based on URL parameters. Whether you're building a multi-brand application or customizing for different clients, this approach is scalable and maintainable.

Start implementing themes in your Angular application today and take your UI customization to the next level!

Previous: Lazy Loading in Angular: Optimize Your Application’s Performance
Next: Creating Dynamic Forms in Angular 19 with Reactive Forms Module