Search code examples
rshinyshinymodules

Creating navbarMenu and tabPanel using shiny modules


I want to create a shiny app that uses navbarMenu() and tabPanel() to display data tables. Instead of writing all of the codes in one app.R file, I plan to use the concept of shiny modules creating R/tabUI.R and R/tabServer.R to generate these tables. However, I run into an error and cannot figure it out. Any suggestions and help are appreciated!

My code:

### R/tabUI.R
tabUI <- function(id) {
    tagList(
        navbarMenu("display table",
            tabPanel(NS(id, "mtcars table"),
            DT::dataTableOutput("table")
        )
    )
 )
}


### R/tabServer.R
tabServer <- function(id) {
    moduleServer(id, function(input, output, session){
        output$table <- DT::renderDataTable(mtcars)
    })
}



### app.R
library(shiny)

ui <- navbarPage("dashboard",
    tabUI("table1")
)

server <- function(input, output, session){
    tabServer("table1")
}

shinyApp(ui=ui, server=server)



Error:

> runApp()
Error: Navigation containers expect a collection of `bslib::nav()`/`shiny::tabPanel()`s and/or `bslib::nav_menu()`/`shiny::navbarMenu()`s. Consider using `header` or `footer` if you wish to place content above (or below) every panel's contents.

Solution

  • You can't use tagList() inside navbarPage() so you need to remove it from the module.

    As a sidenote, you should define ns <- NS(id) at the beginning of the module and then wrap all ids in ns(). In your code, the table id was not wrapped in ns() so it wasn't displayed.

    Fixed code:

    ### R/tabUI.R
    tabUI <- function(id) {
      ns <- NS(id)
      
        navbarMenu("display table",
                   tabPanel(ns("mtcars table"),
                            DT::dataTableOutput(ns("table"))
                   )
        )
      
    }
    
    
    ### R/tabServer.R
    tabServer <- function(id) {
      moduleServer(id, function(input, output, session){
        output$table <- DT::renderDataTable(mtcars)
      })
    }
    
    
    
    ### app.R
    library(shiny)
    
    ui <- navbarPage("dashboard",
                     tabUI("table1")
    )
    
    server <- function(input, output, session){
      tabServer("table1")
    }
    
    shinyApp(ui=ui, server=server)