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

带登录启动页的Shiny应用主题切换失效问题求助

解决Shinymanager添加后Bslib主题切换失效问题

问题核心在于shinymanager的认证框架会改变UI的层级结构,且主题切换逻辑需要在用户认证通过后才能正常触发(认证前input$theme未初始化)。以下是具体修复方案:

关键问题分析

  • 原代码中login_pwd()(set_labels)是全局配置,无需重复放在ui和secure_app的head_auth参数中
  • 主题切换的observe在认证前就会执行,此时input$theme不存在,导致逻辑失效
  • corresp列表冗余,直接映射主题名称到bs_theme对象更高效

修复后的完整代码

library(shinymanager)
library(bslib)
library(shiny)

# 设置登录凭证(建议实际项目中不要用环境变量存密码)
Sys.setenv(LOGIN_USER = "a")
Sys.setenv(PWD_USER = "a")

# 定义主题对象
theme_list <- list(
  cosmo = bslib::bs_theme(bootswatch = "cosmo", version = 5),
  solar = bslib::bs_theme(bootswatch = "solar", version = 5),
  yeti = bslib::bs_theme(bootswatch = "yeti", version = 5)
)

# 全局设置登录页面标签
set_labels(
  language = "en",
  title = "Please authenticate",
  username = "Username:",
  password = "Password:",
  button = "Login",
  error = "Username or password are incorrect"
)

ui <- navbarPage(
  theme = theme_list$cosmo,  # 初始主题
  inverse = FALSE,
  windowTitle = "App",
  title = "App",
  id = "main_menu",
  
  tabPanel(
    title = "Themes",
    selectInput(
      inputId = "theme",
      label = "Themes :",
      choices = c(
        "Cosmo" = "cosmo",
        "Solar" = "solar",
        "Yeti" = "yeti"
      )
    )
  )
)

server <- function(input, output, session) {
  
  # 认证逻辑
  credentials <- data.frame(
    user = Sys.getenv("LOGIN_USER"),
    password = Sys.getenv("PWD_USER"),
    stringsAsFactors = FALSE
  )
  
  res_auth <- shinymanager::secure_server(
    check_credentials = shinymanager::check_credentials(credentials)
  )
  
  # 认证成功后触发主题切换逻辑
  observeEvent(res_auth$user, {
    # 监听主题选择变化
    observeEvent(input$theme, {
      session$setCurrentTheme(theme_list[[input$theme]])
    }, ignoreInit = FALSE)  # 初始化时应用当前选择的主题
  })
  
}

shinyApp(
  ui = shinymanager::secure_app(ui = ui),
  server = server
)

核心改动说明

  1. 简化登录配置:将set_labels作为全局调用,不再重复传入UI组件
  2. 主题列表优化:用命名列表直接存储主题对象,避免get()函数的潜在风险
  3. 认证后触发逻辑:用observeEvent(res_auth$user)确保主题切换代码在用户登录后才执行,此时input$theme已初始化
  4. 明确初始化行为:ignoreInit = FALSE保证页面加载时应用选中的初始主题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 18:56:20