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?
2
Answers
private void darkMode()
{
_currentTheme = _isDarkMode ? ApplicationTheme.DefaultTheme : ApplicationTheme.DarkTheme;
_isDarkMode = !_isDarkMode;
}
I’m facing similar issue while using blazor web app template (with interactive render mode set to server) which till now haven’t found any fix for it. Nevertheless, I’m not facing the issue with blazor WASM standalone App template.