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

如何实现本地与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)

关键调整点

  1. 用session$clientData$url_pathname动态获取应用实际路径,避免硬编码根路径导致的错误
  2. 导航链接通过基础路径拼接,生成适配环境的相对链接
  3. 服务器端初始化路由器时传入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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 17:16:09