Theme toggle PrimeNG

While working with PrimeNG and PrimeFlex in my Angular 17 standalone app that uses SSR, one feature really impressed me: the out-of-the-box themes. In contrast to Material UI, PrimeNG supplies a rich set of ready-made themes that you can seamlessly integrate into your project.

The true highlight, however, was adding a theme switcher that lets users customize their interface. Achieving this requires surprisingly minimal code. In this walkthrough, I'll show you exactly how.

Preparing Your Application for Theme Configuration:

First, install the required package via npm or yarn.

npm install primeng --save

Add Styles to angular.json:

Your angular.json file must reference the necessary style files. Shown below is my directory layout along with how I referenced it in angular.json.

Folder Structure

Every stylesheet pulled in one of the preinstalled PrimeNG themes supplied via the resources directory.

 //angular.json 
 "styles": [
              "src/styles.css",
              {
                "input": "src/app/styles/lara-dark-teal.scss",
                "bundleName": "lara-dark-teal",
                "inject": false
              },
              {
                "input": "src/app/styles/lara-light-teal.scss",
                "bundleName": "lara-light-teal",
                "inject": false
              }
            ],
Enter fullscreen mode Exit fullscreen mode

With this setup, the CSS files are ensured to be included in your production dist directory when the build runs.

  1. Configuring the Initial Theme (index.html):

Add the Stylesheet: Inside your index.html, insert the link to your selected default theme's stylesheet and give it an identifier so the service can reference it later:

<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>Theme Switcher</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link id="app-theme" rel="stylesheet" type="text/css" href="lara-light-teal.css">

  <link rel="stylesheet" href="https://unpkg.com/primeflex@latest/primeflex.css">
</head>

<body class="">
  <app-root></app-root>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode
  1. Dynamic Theme Switching with a Service:

Build a service that handles theme toggling. Provide it at the root component level so it can be injected anywhere in the app:

//themes.service.ts
import { Inject, Injectable } from '@angular/core';
import { DOCUMENT } from '@angular/common';

@Injectable({
    providedIn: 'root',
})
export class ThemeService {

    constructor(@Inject(DOCUMENT) private document: Document) {}

    switchTheme(theme: string) {

        let themeLink = this.document.getElementById('app-theme') as HTMLLinkElement;

        if (themeLink) {
            themeLink.href = theme + '.css';
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
  1. Consuming the service within a component:

Bring the ThemeService and Document into your component by injecting them:

  constructor(private themeService: ThemeService) {

  }
  checked: boolean = false;

  changeTheme() {
    let theme = (this.checked) ? "lara-dark-teal" : "lara-light-teal"
    this.themeService.switchTheme(theme);

  }

}

Enter fullscreen mode Exit fullscreen mode

Render the toggle control using PrimeNG’s p-toggle component. Connect its checked state to a boolean property, and call the changeTheme() handler upon user interaction. For a polished look, make use of pi-icons from PrimeNG’s icon set.

<p-toolbar styleClass="bg-primary shadow-2  opacity-80">

    <div class="flex-grow">
        My Theme Switcher
    </div>
    <p-toggleButton styleClass="bg-primary shadow-2 text-white" [(ngModel)]="checked" onIcon="pi pi-sun"
        offIcon="pi pi-moon" (click)="changeTheme()" />

</p-toolbar>
Enter fullscreen mode Exit fullscreen mode

Separation of Concerns: Theme logic lives entirely within the service, so your component stays lean and purposeful.

Enhanced Readability: The implementation is cleanly organized, making it straightforward for any developer to follow.

Developer Delight: PrimeNG simplifies the heavy lifting, letting you build a smooth theme-switching experience in your Angular 17 app with ease.