reactR icon indicating copy to clipboard operation
reactR copied to clipboard

server-side rendering in Shiny

Open timelyportfolio opened this issue 5 months ago • 0 comments

For another very likely useless example/hack, we can sort-of do server-side rendering in Shiny. In reality we already are doing this with the input mechanism, but in an attempt to make this more obvious, let's build a Shiny input that is simply a container in which we will hydrate and render what we receive from Shiny. In this case we will send json-ified htmltools:tags. These could also be real React components as well.

library(shiny)
library(reactR)

ui <- tagList(
  tags$script(HTML(
"
  const ContainerInput = ({ configuration, value, setValue }) => {
    // hydrate and render value as children of this container
    //   ignore value
    return React.createElement(
      'div',
      configuration,
      value.map(function(x) {return reactR.hydrate({}, x)})
    )
  };
  reactR.reactShinyInput('.container', 'container', ContainerInput); 
"    
  )),
  createReactShinyInput(
    inputId = "testcontainer",
    class = "container",
    dependencies = list(list()), # fake dependency since we will define in script
    configuration = list(),
    default = list()
  )
)

server <- function(input, output, session) {
  observe({
    invalidateLater(1000, session)
    # send some tags as json in value to render in the container
    session$sendInputMessage(
      'testcontainer',
      list(
        value = jsonlite::toJSON(
          list(
            tags$h1("server side (sort-of) rendered"),
            do.call(tags$ul,lapply(rnorm(10), function(x) tags$li(as.character(x))))
          ),
          auto_unbox = TRUE,
          force = TRUE
        )
      )
    )
  })
}

shinyApp(ui, server)

Image

timelyportfolio avatar Jul 25 '25 01:07 timelyportfolio