Linking to a tab or panel of a shiny app

The following solution is based on the inputs I got from the comments.

Note that updateTabsetPanel() belongs to shiny while updateTabItems() is a function of the shinydashboard package. They seem to work interchangeably.

library(shiny)
library(shinydashboard)

# UI ---------------------------------------------------------------------

ui <- fluidPage(
  tabsetPanel(
    id = "panels",
    tabPanel(
      "A",
      p(),
      actionLink("link_to_tabpanel_b", "Link to panel B")
    ),
    tabPanel(
      "B",
      h3("Some information"),
      tags$li("Item 1"),
      tags$li("Item 2"),
      actionLink("link_to_tabpanel_a", "Link to panel A")
    )
  )
)

# Server ------------------------------------------------------------------

server <- function(input, output, session) {
#   observeEvent(input$link_to_tabpanel_b, {
#     tags$a(href = "#tab-4527-2")
#   })
  observeEvent(input$link_to_tabpanel_b, {
    newvalue <- "B"
    updateTabItems(session, "panels", newvalue)
  })
  observeEvent(input$link_to_tabpanel_a, {
    newvalue <- "A"
    updateTabsetPanel(session, "panels", newvalue)
  })
}

shinyApp(ui, server)

You can give your tabsetPanel an id and use updateTabsetPanel with your observeEvent

library(shiny)

# UI ---------------------------------------------------------------------

ui <- fluidPage(
  tabsetPanel(id = "demo",
    tabPanel(
      "A",
      p(),
      actionLink("link_to_tabpanel_b", "Link to panel B")
    ),
    tabPanel(
      "B",
      h3("Some information"),
      tags$li("Item 1"),
      tags$li("Item 2")
    )
  )
)

# Server ------------------------------------------------------------------

server <- function(input, output, session) {
  observeEvent(input$link_to_tabpanel_b, {
    updateTabsetPanel(session, "demo", "B")
  })
}

shinyApp(ui, server)

We have just released a routing library, which makes linking in Shiny easy. Here's how it looks like in a nutshell.

make_router(
   route("<your_app_url>/main",  main_page_shiny_ui),
   route("<your_app_url>/other", other_page_shiny_ui)
)

More information can be found in this blog post.


I was struggling with the same issue and really wanted to link to a different tab via the URL. Thanks to the simple example of thesadie and by using an observe to parse inputs from the url, for me the following worked (and made it possible to switch the tab by adding /?tab=B to the URL, e.g. http://localhost:1234/?tab=B):

library(shiny)

# UI ---------------------------------------------------------------------

ui <- fluidPage(
  tabsetPanel(id = "demo",
              tabPanel(
                "A",
                p(),
                actionLink("link_to_tabpanel_b", "Link to panel B")
              ),
              tabPanel(
                "B",
                h3("Some information"),
                tags$li("Item 1"),
                tags$li("Item 2")
              )
  )
)

# Server ------------------------------------------------------------------

server <- function(input, output, session) {
  # Allow url parsing
  observe({
    query <- parseQueryString(session$clientData$url_search)
    if (!is.null(query)) {
      for (name in names(query)) {
        if (name == "tab") {
          # Change tab
          try(updateTabsetPanel(session, "demo", selected = query[[name]]))
        } else {
          # Update inputs - this part is not really necessary if you just want to change the tabs, 
          # but I also needed to update other inputs from the url
          try(updateTextInput(session, name, value = query[[name]]), silent = TRUE)
        }
      }
    } 
  })
  
  observeEvent(input$link_to_tabpanel_b, {
    updateTabsetPanel(session, "demo", "B")
  })
}

shinyApp(ui, server)