skip to Main Content

On https://docs.blazorbootstrap.com/ there is a light-dark theme switcher near Github and Twitter links: Light and dark theme switcher on blazorbootstrap site

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


  1. private void darkMode()
    {
    _currentTheme = _isDarkMode ? ApplicationTheme.DefaultTheme : ApplicationTheme.DarkTheme;
    _isDarkMode = !_isDarkMode;
    }

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search