如何实现本地与shinyapps.io通用的R Shiny应用页面路由
解决shinyapps.io上shiny.router的URL重定向与子页面导航问题
问题说明
本地使用shiny.router实现URL切换页面内容正常,但部署到shinyapps.io后遇到两个问题:
- 主应用URL会重定向到带随机后缀的地址
- 子页面链接指向无内容的根域名路径
期望URL结构:
- 主页:
https://cjrace.shinyapps.io/shiny-routing-reprex/ - 子页面:
https://cjrace.shinyapps.io/shiny-routing-reprex/subpage
解决方案一:适配shinyapps.io的shiny.router配置
通过动态获取应用基础路径,替换硬编码的根路径,让路由同时适配本地和服务器环境:
library(shiny) library(shiny.router) main_page <- function() { div(h1("Main page"), p("Some main text.")) } sub_page <- function() { div(h1("Sub page"), p("Some subtext.")) } # 动态获取应用基础路径(兼容本地与shinyapps.io) get_app_base_path <- function() { session <- shiny::getDefaultReactiveDomain() if (!is.null(session)) { return(session$clientData$url_pathname) } else { return("/") } } ui <- fluidPage( tags$ul( tags$li(tags$a("Main page", href = get_app_base_path())), tags$li(tags$a("Sub page", href = paste0(get_app_base_path(), "subpage"))) ), router_ui( route("/", main_page()), route("subpage", sub_page()) ) ) server <- function(input, output, session) { # 初始化路由器时指定应用基础路径 shiny.router::router_server( path = session$clientData$url_pathname ) } shinyApp(ui = ui, server = server)
关键调整点
- 用
session$clientData$url_pathname动态获取应用实际路径,避免硬编码根路径导致的错误 - 导航链接通过基础路径拼接,生成适配环境的相对链接
- 服务器端初始化路由器时传入
path参数,让shiny.router适配shinyapps.io的路由规则
解决方案二:使用shiny原生函数实现路由
如果不想依赖第三方包,可以用shiny原生的URL操作函数实现页面切换:
library(shiny) main_page <- function() { div(h1("Main page"), p("Some main text.")) } sub_page <- function() { div(h1("Sub page"), p("Some subtext.")) } ui <- fluidPage( tags$ul( tags$li(actionLink("go_main", "Main page")), tags$li(actionLink("go_sub", "Sub page")) ), uiOutput("main_content") ) server <- function(input, output, session) { # 点击链接时更新URL片段 observeEvent(input$go_main, { updateQueryString("", mode = "push", session = session) }) observeEvent(input$go_sub, { updateQueryString("subpage", mode = "push", session = session) }) # 根据URL片段渲染对应页面 output$main_content <- renderUI({ url_fragment <- getQueryString(session)$_escaped_fragment_ if (url_fragment == "subpage") { sub_page() } else { main_page() } }) } shinyApp(ui = ui, server = server)
方案优势
- 完全依赖shiny原生函数,无需额外包的适配工作
- 通过
updateQueryString和getQueryString实现URL与页面内容的联动
内容的提问来源于stack exchange,提问作者C Race
相关产品推荐
相关产品推荐

