Shiny Modules for Code Reuse
Encapsulate UI and server logic into namespaced, reusable modules.
Why Shiny Modules?
As Shiny apps grow, having all UI and server code in one file becomes unmanageable. Modules are self-contained pieces of Shiny UI + server logic with namespaced IDs. You can reuse the same module multiple times in one app without ID conflicts, and test modules independently.
# Problem: without modules, ID conflicts arise
# ui <- fluidPage(
# selectInput('dataset', ...), # used by plot1 AND plot2!
# selectInput('dataset', ...) # duplicate ID — BROKEN
# )
# With modules: each instance has its own namespaced IDs
# plotModule('plot1', ...) -> input$plot1-dataset
# plotModule('plot2', ...) -> input$plot2-datasetNS() — The Namespace Function
Every module UI function starts with ns <- NS(id). All UI element IDs passed to Shiny must be wrapped in ns(). This prepends id- to each ID, creating a namespace that prevents conflicts between module instances.
# Module UI function
filter_plot_ui <- function(id) {
ns <- NS(id) # create the namespace function
tagList(
selectInput(ns('dataset'), 'Choose Dataset:',
choices = c('mtcars', 'iris', 'airquality')),
sliderInput(ns('n_rows'), 'Rows to show:', 1, 50, 20),
plotOutput(ns('scatter_plot'))
)
}All lessons in this course
- Reactive Programming Deep Dive
- Shiny Modules for Code Reuse
- Dynamic UI with renderUI and insertUI
- Deploying Shiny Apps