I have a simple web application which is developed by Angular 18. I am going to bind a dynamic attribute to the <html>
tag in the index.html file as follows:
<!doctype html>
<html lang="en" class="h-100" [data-bs-theme]="theme">
<head>
<meta charset="utf-8">
<title>My app</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body class="h-100">
<app-root></app-root>
</body>
</html>
I tried to define the theme
property in the main.ts and app.component.ts files but it does not work!
Is it possible to do that?
Where can I define and programmatically change the theme
property?
What is the best practice to meet this requirement?
You can get the HTML element using document.querySelector
and set the value manually.
The reason you are not getting the variable updated, is because all the content inside the app-root
is where the angular application exists, so only inside this scope the bindings work. Hence the body and HTML tags do not have any working angular functionality.
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
@Component({
selector: 'app-root',
standalone: true,
template: `
<h1>Hello from {{ name }}!</h1>
<a target="_blank" href="https://angular.dev/overview">
Learn more about Angular
</a>
<button (click)="changeBsValue('dark')"> change theme </button>
`,
})
export class App {
name = 'Angular';
ngOnInit() {
this.changeBsValue('light');
}
changeBsValue(value: string) {
const html = document.querySelector('html');
html!.setAttribute('data-bs-theme', value);
}
}
bootstrapApplication(App);
<!DOCTYPE html>
<html lang="en" [data-bs-theme]="''">
<head>
<title>My app</title>
<meta charset="UTF-8" />
<base href="/" />
</head>
<body>
<app-root>Loading...</app-root>
</body>
</html>
/* Add application styles & imports to this file! */
html[data-bs-theme='light'] h1 {
background-color: red;
}
html[data-bs-theme='dark'] h1 {
background-color: black;
color: white;
}