knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) library(shinyreprex)
There is a single exported function, reprex_reactive``, that takes a reactive object and converts
it into a script that can be reused outside of the Shiny application to reproduce the result
of the reactive. This can be sent to a simpleverbatimTextOutputor something more UX
friendly such as the{highlighter}` package to display the script in the UI.
reprex_reactive call to EventThe code to reproduce a given reactive will be updated whenever an input or reactive feeding into the provided reactive is updated, therefore it is recommended to have the reactive as an event attached.
width_range <- reactive({ iris_filt <- dplyr::filter(iris, Species == "versicolor") range(iris_filt$Petal.Width) }) # Good repro_range <- reactive(reprex_reactive(width_range)) |> bindEvent(width_range()) # Bad repro_range <- reactive(reprex_reactive(width_range))
This is general best-practice when developing Shiny applications, but avoid putting code
for its side effects in reactive expressions, and instead create smaller reactive calls,
and have observers running the code not intended for reproducing outputs.
# Good width_range <- reactive({ iris_filt <- dplyr::filter(iris, Species == "versicolor") range(iris_filt$Petal.Width) }) observe({ updateSliderInput("width", width_range()) }) # Bad width_range <- reactive({ iris_filt <- dplyr::filter(iris, Species == "versicolor") widths <- range(iris_filt$Petal.Width) updateSliderInput("width", widths) widths }) summary_data <- reactive({ iris_filt <- dplyr::filter(iris, Species == "versicolor") shinyjs::toggle("table", condition = nrow(iris_filt) > 0L) dplyr::summarise(iris_filt, dplyr::across(where(is.numeric), mean)) })
In order that developers can easily recreate outputs generated in Shiny applications, add any business logic, such as ETL, data manipulation and modelling, to a separate package. This will allow users to recreate the tables and plots generated in the app without having to install all the packages associated with the application.
If you are using secrets, such as environment variables, make sure that they are defined within a reactive expression. If it is defined in the module, or in the global environment, the secret will be written in the assignment.
# Good moduleServer(id, function(input, output, session) { my_reactive <- reactive({ api_key <- Sys.getenv("MY_API_KEY") ... }) }) # Bad moduleServer(id, function(input, output, session) { api_key <- Sys.getenv("MY_API_KEY") my_reactive <- reactive({ ... }) })
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.