Search code examples
rshinyshiny-servershinyapps

How can I combine two shiny apps?


I have 2 different Shinnyapps in 2 different directories. And let's assume Shinyapp1's UI and server and Shinnyapp2's UI and server as given. How can I create 1 Shinyapp by combining these 2 different apps without rewriting the code? or if you know any GitHub example for this? Many thanks in advance.

 library(shiny)

ui <- navbarPage("Combine 2 Shinyapps",
           tabPanel("Shinyapp1"),
           tabPanel("Shinyapp2")
)

server <- function(input, output, session) { 
}
shinyApp(ui, server)

Solution

  • Here is an example using iframes (an approach I already mentioned in your duplicated earlier question).

    In the global part im writing two dummy app.R files which are started in a seperate R process via callr::r_bg:

    library(shiny)
    library(callr)
    
    makeDir <- function(dir){
      if(!dir.exists(dir)){
        dir.create(dir, recursive = TRUE)
      }}
    
    lapply(c("app1", "app2"), makeDir)
    
    writeLines(text = 'ui <- fluidPage(p("App 1 content"), 
    sliderInput("obs", "Number of observations:",
        min = 0, max = 1000, value = 500
      ))
    server <- function(input, output, session) {}
    shinyApp(ui, server)', con = "app1/app.R")
    
    writeLines(text = 'ui <- fluidPage(p("App 2 content"),
    sliderInput("obs", "Number of observations:",
        min = 0, max = 100, value = 50
      ))
    server <- function(input, output, session) {}
    shinyApp(ui, server)', con = "app2/app.R")
    
    r_bg(function(){
      shiny::runApp(
      appDir = "app1",
      port = 3939,
      launch.browser = FALSE,
      host = "127.0.0.1"
    )}, supervise = TRUE)
    
    r_bg(function(){
      shiny::runApp(
      appDir = "app2",
      port = 4040,
      launch.browser = FALSE,
      host = "127.0.0.1"
    )}, supervise = TRUE)
    
    
    ui <- navbarPage("Combine 2 Shinyapps",
                     tabPanel("Shinyapp1", tags$iframe(src="http://127.0.0.1:3939/", height="900vh", width="100%", frameborder="0", scrolling="yes")),
                     tabPanel("Shinyapp2", tags$iframe(src="http://127.0.0.1:4040/", height="900vh", width="100%", frameborder="0", scrolling="yes"))
    )
    
    server <- function(input, output, session) {
      
    }
    
    mainApp <- shinyApp(ui, server)
    
    runApp(mainApp)
    

    Another (better) approach would be to wrap both apps in separate modules with their own name space. This is less computationally intensive (a single R process instead of 3) but it would require to rearrange the code (which is not desired by OP: without rewriting the code).