Scoping rules for Shiny apps
Where you define objects will determine where the objects are visible. There are three different levels of visibility that you’ll want to be aware of when writing Shiny apps. Some objects are visible within the
server code of each user session; other objects are visible in the
server code across all sessions (multiple users could use a shared variable); and yet others are visible in the
server and the
ui code across all user sessions.
server function takes two arguments,
The function is called once for each session. In other words, the
server function is called each time a web browser is pointed to the Shiny application.
Everything within this function is instantiated separately for each session.
This includes the
output objects that are passed to it: each session has its own
output objects, visible within this function.
Other objects inside the function, such as variables and functions, are also instantiated for each session. In this example, each session will have its own variable named
startTime, which records the start time for the session:
Objects visible across all sessions
You might want some objects to be visible across all sessions. For example, if you have large data structures, or if you have utility functions that are not reactive (ones that don’t involve the
output objects), then you can create these objects once and share them across all user sessions, by placing them in
app.R, but outside of the
server function definition.
You could put
utilityFunction inside the
server function, but doing so will be less efficient, because they will be created each time a user connects.
If the objects change, then the changed objects will be visible in every user session. But note that you would need to use the
<<- assignment operator to change
bigDataSet, because the
<- operator only assigns values in the local environment.
Things work this way because
app.R is sourced when you start your Shiny app. Everything in this script is run immediately. However, your
server function is only actually called when a web browser connects and a new session is started
Objects defined in
global.R are similar to those defined in
app.R outside of the
server function definition, with one important difference: they are also visible to the code in the
ui object. This is because they are loaded into the global environment of the R session; all R code in a Shiny app is run in the global environment or a child of it.
In practice, there aren’t many times where it’s necessary to share variables between
ui. The code in
ui is run once, when the Shiny app is started and it generates an HTML file which is cached and sent to each web browser that connects. This may be useful for setting some shared configuration options.
Scope for included R files
If you want to split the
ui code into multiple files, you can use
source(local = TRUE) to load each file. You can think of this as putting the code in-line, so the code from the sourced files will receive the same scope as if you copied and pasted the text right there.
app.R file shows how sourced files will be scoped:
If you use the default value of
local = FALSE, then the file will be sourced in the global environment.
If you have questions about this article or would like to discuss ideas presented here, please post on RStudio Community. Our developers monitor these forums and answer questions periodically. See help for more help with all things Shiny.