Skip to contents

The goal of {scenes} is to make it easy to switch a {shiny} app between alternative UIs. It was designed to abstract the login-wrapper concept implemented in {shinyslack}.


Install the released version of {scenes} from CRAN:

Or install the development version of scenes from GitHub with:

# install.packages("remotes")

Use Cases

You can see a demonstration of {scenes} here.

Some examples of how you might use {scenes} to switch between different UIs in a Shiny app:

  • Login Wrapper: Use {scenes} to switch between a login page and the main content of the app. This is the original use case for {scenes}. It ws designed to abstract the login-wrapper concept implemented in {shinyslack}.

  • App Modes: Use {scenes} to switch between different modes of the app, such as a view-only mode and an edit mode, via a query parameter (

  • User Roles: Use {scenes} to switch between different UIs based on user roles. For example, a non-admin user might see a different UI than an admin user.

The Login Wrapper example might look like this:


# Define the different scenes for the app
login_ui <- fluidPage(
  textInput("username", "Username"),
  passwordInput("password", "Password"),
  actionButton("login", "Login")

main_ui <- fluidPage(

# Use the `set_scene()` function to define the different scenes, and
# `change_scene()` to switch between them.
ui <- change_scene(
      validation_fn = my_validation_fn
  fall_through = login_ui

server <- function(input, output, session) {
  observeEvent(input$login, {
    use_cookies_package_to_save_cookie_fn(input$username, input$password)

  output$username <- renderText({

shinyApp(ui = ui, server = server)

See {shinyslack} for a fully implemented example.

Similar Packages

Other packages have implemented features in this domain.

  • {brochure}: This package appears to have a great deal of overlap with {scenes}. Colin Fay’s implementation appears to potentially be more robust and more complete than {scenes}, but at the cost of diverging farther from a “normal” shiny app.
  • {shiny.router}: This package from Appsilon appears to be conceptually similar to {scenes}, but focused on routing based on URL. Of the three packages listed here, this is the only one available on CRAN.
  • {blaze}: This package from Nate Teetor also focuses on routing based on URL. The resulting shiny apps are switched via the server function.

Code of Conduct

Please note that the scenes project is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.