You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Blazor中结合Bootstrap正确实现深色主题切换?

解决Blazor中Bootstrap主题切换后页面跳转丢失的问题

问题根源

你使用InteractiveAuto渲染模式时,切换到服务器端渲染(SSR)的页面时,服务器无法读取客户端localStorage中的主题设置,生成的<html>元素没有data-bs-theme属性,因此默认显示浅色主题;而刷新页面时客户端自执行JS会读取localStorage并设置主题,所以又恢复深色。

解决方案

1. 修改JavaScript代码,同步主题到Cookie

服务器无法读取localStorage但可以读取Cookie,因此需要把主题同时存入localStorage和Cookie:

function setTheme(theme) {
    localStorage.setItem('theme', theme);
    // 设置Cookie,有效期1年,确保全站可访问
    document.cookie = `theme=${theme}; path=/; max-age=31536000; SameSite=Lax`;
    document.documentElement.setAttribute('data-bs-theme', theme);
}

function getTheme() {
    // 优先从localStorage取,没有则从Cookie解析
    let theme = localStorage.getItem('theme');
    if (!theme) {
        const cookies = document.cookie.split(';').map(c => c.trim());
        const themeCookie = cookies.find(c => c.startsWith('theme='));
        theme = themeCookie ? themeCookie.split('=')[1] : 'light';
    }
    return theme;
}

// 初始加载时应用主题
(function() {
    const theme = getTheme();
    setTheme(theme);
})();

2. 服务器端渲染时设置<html>主题属性

在根布局文件(如_Layout.cshtml)中,读取Cookie并为<html>元素设置data-bs-theme属性:

<!DOCTYPE html>
<html lang="zh-CN" data-bs-theme="@(Context.Request.Cookies["theme"] ?? "light")">
<head>
    <!-- 页面头部内容 -->
</head>
<body>
    @RenderBody()
    <!-- 加载你的JavaScript文件 -->
</body>
</html>

3. 优化Blazor组件的主题状态同步

修改组件代码,确保服务器端和客户端渲染时都能获取正确的主题值,避免切换按钮显示错误:

@rendermode InteractiveAuto
@inject IJSRuntime Js
@inject IHttpContextAccessor HttpContextAccessor
<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 = "light";

    protected override async Task OnInitializedAsync()
    {
        if (OperatingSystem.IsBrowser())
        {
            // 客户端环境:从JS获取主题
            _theme = await Js.InvokeAsync<string>("getTheme");
        }
        else
        {
            // 服务器端环境:从Cookie获取主题
            _theme = HttpContextAccessor.HttpContext?.Request.Cookies["theme"] ?? "light";
        }
    }

    private async Task SetTheme(string theme)
    {
        await Js.InvokeVoidAsync("setTheme", theme);
        _theme = theme;
    }
}

额外配置

在Program.cs中注册IHttpContextAccessor服务:

builder.Services.AddHttpContextAccessor();

修改完成后,无论是服务器端渲染还是客户端渲染,主题都会保持一致,页面切换时不会出现主题丢失的问题。

内容的提问来源于stack exchange,提问作者Tomasz Sikora

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 20:35:07