November 11, 2024
You could call modules special functions.
Using functions in a Shiny app is common:
value_box()
)That works well for code that is completely on the ui or server side.
For code that spans both the ui and the server, you need a new technique: modules
A module consists of some UI code that works together with some server code
Modules are special because they create their own namespace: things like input and output ids are isolated from the rest of the app
There are two main reasons to work with modules:
Because a module creates its own namespace, you can write and run code in isolation. You don’t need to worry about what’s going on outside the module. And remember, ids needed to be unique!
Because a module is basically a function, it comes with all the benefits that functions have.
A module has two parts, and is basically a mini-app:
The module UI, which generates the HTML and runs code inside the ui()
function
The module server, which runs code inside the server()
function
library(shiny)
numberModUI <- function(id) {
ns <- NS(id)
tagList(
numericInput(inputId = ns("number"),
label = "Enter a number",
value = 0),
actionButton(inputId = ns("button"),
label = "Click me"),
textOutput(outputId = ns("text"))
)
}
numberModServer <- function(id) {
moduleServer(id, function(input, output, session) {
output$text <- renderText({
input$number^2
}) |> bindEvent(input$button)
})
}
ui <- fluidPage(
numberModUI("numbers")
)
server <- function(input, output, session) {
numberModServer("numbers")
}
shinyApp(ui, server)
library(shiny)
numberModUI <- function(id) {
ns <- NS(id)
tagList(
numericInput(inputId = ns("number"),
label = "Enter a number",
value = 0),
actionButton(inputId = ns("button"),
label = "Click me"),
textOutput(outputId = ns("text"))
)
}
numberModServer <- function(id) {
moduleServer(id, function(input, output, session) {
output$text <- renderText({
input$number^2
}) |> bindEvent(input$button)
})
}
ui <- fluidPage(
numberModUI("numbers")
)
server <- function(input, output, session) {
numberModServer("numbers")
}
shinyApp(ui, server)
library(shiny)
numberModUI <- function(id) {
ns <- NS(id)
tagList(
numericInput(inputId = ns("number"),
label = "Enter a number",
value = 0),
actionButton(inputId = ns("button"),
label = "Click me"),
textOutput(outputId = ns("text"))
)
}
numberModServer <- function(id) {
moduleServer(id, function(input, output, session) {
output$text <- renderText({
input$number^2
}) |> bindEvent(input$button)
})
}
ui <- fluidPage(
numberModUI("numbers")
)
server <- function(input, output, session) {
numberModServer("numbers")
}
shinyApp(ui, server)
library(shiny)
numberModUI <- function(id) {
ns <- NS(id)
tagList(
numericInput(inputId = ns("number"),
label = "Enter a number",
value = 0),
actionButton(inputId = ns("button"),
label = "Click me"),
textOutput(outputId = ns("text"))
)
}
numberModServer <- function(id) {
moduleServer(id, function(input, output, session) {
output$text <- renderText({
input$number^2
}) |> bindEvent(input$button)
})
}
ui <- fluidPage(
numberModUI("numbers")
)
server <- function(input, output, session) {
numberModServer("numbers")
}
shinyApp(ui, server)
You can simply put the module functions in the app.R
file (you call this inline).
Other options:
Put the module in a separate R script in the /R folder. Shiny will automatically source it.
Put the module in a separate R script in any other folder, and source it using source(“./my_modules/random.R”)
.