On https://docs.blazorbootstrap.com/ there is a light-dark theme switcher near Github and Twitter links: 
However there is no explanation how to do it. Bootstrap 5 has now support for dark theme if you apply data-bs-theme="dark" attribute to <html> element https://getbootstrap.com/docs/5.3/customize/color-modes/#enable-dark-mode
I tried to make it work in blazor with javascript functions that read and write selected theme to local storage:
function setTheme(theme) { localStorage.setItem('theme', theme); // set data-bs-theme to the body element document.documentElement.setAttribute('data-bs-theme', theme);}function getTheme() { console.log("Getting theme: " + localStorage.getItem('theme')); return localStorage.getItem('theme');}(function() { let theme = localStorage.getItem('theme'); if (theme == null) { setTheme('light'); } else { setTheme(theme); }})();I also have my theme-switching component that uses IJSRuntime to trigger theme change:
@rendermode InteractiveAuto@inject IJSRuntime Js<div class="nav-item px-3"> @if(_theme == "dark") {<a class="nav-link" @onclick='() => SetTheme("light")'><Icon Class="px-3" Name=IconName.Moon />Light theme</a> } else {<a class="nav-link" @onclick='() => SetTheme("dark")'><Icon Class="px-3" Name=IconName.Sun />Dark theme</a> }</div>@code { private string _theme = ""; protected override async Task OnAfterRenderAsync(bool firstRender) { _theme = await Js.InvokeAsync<string>("getTheme"); } private Task SetTheme(string theme) { Js.InvokeVoidAsync("setTheme", theme); _theme = theme; return Task.CompletedTask; }}And this works until I try to go to a different page. Then the html element is overwritten and my data-bs-theme attribute is gone and everything becomes light-themed. When I refresh the page however, everything goes to dark theme again because of the immediately invoked function from javascript.
How to implement it properly?