Skip to contents

Introduction

To use pages with shinyMaterialUI, you might need to use a router service. This document shows examples using the reactRouter and shiny.router R packages.

Examples using {reactRouter}

An example using reactRouter client routing (no server):

# install.packages("reactRouter")
library(reactRouter)
library(shinyMaterialUI)
library(shiny)

reactRouter::HashRouter(
  AppBar(
    position = "static",
    Toolbar(
      Typography(
        variant = "h6",
        component = "div",
        "shinyMaterialUI"
      ),
      reactRouter::NavLink(
        to = "/",
        style = JS('({isActive}) => { return isActive ? {color: "white"} : {color: "white"}; }'),
        Button(
          color = "inherit",
          "Home"
        )
      ),
      reactRouter::NavLink(
        to = "/analysis",
        style = JS('({isActive}) => { return isActive ? {color: "white"} : {color: "white"}; }'),
        Button(
          color = "inherit",
          "Analysis"
        )
      )
    )
  ),
  Box(
    sx = list(p = 3),
    reactRouter::Routes(
      reactRouter::Route(
        path = "/",
        element = div(
          tags$h3("Home page"),
          p("A basic example of reactRouter with shinyMaterialUI."),
          p("Content home")
        )
      ),
      reactRouter::Route(
        path = "/analysis",
        element = div(
          tags$h3("Analysis"),
          p("Content analysis")
          )
      ),
      reactRouter::Route(path = "*", element = div(tags$p("Error 404")))
    )
  )
)

An example with reactRouter in an R Shiny app (with server):

# install.packages("reactRouter")
library(reactRouter)
library(shinyMaterialUI)
library(shiny)

ui <- shinyMaterialUIPage(
  reactRouter::HashRouter(
    CssBaseline(
    Typography("reactRouter with shinyMaterialUI", variant = "h5", m = 2),
    Stack(
      direction = "row", spacing = 2, p = 2,
      Paper(
        MenuList(
          reactRouter::NavLink.shinyInput(
            inputId = "page_home",
            to = "/",
            style = JS('({isActive}) => { return isActive ? {color: "red", textDecoration:"none"} : { textDecoration: "none" }; }'),
            MenuItem(
              "home"
            )
          ),
          br(),
          reactRouter::NavLink.shinyInput(
            inputId = "page_analysis",
            to = "/analysis",
            style = JS('({isActive}) => { return isActive ? {color: "red", textDecoration: "none"} : { textDecoration: "none" }; }'),
            MenuItem(
              "Analysis"
            )
          ),
          br(),
          reactRouter::NavLink.shinyInput(
            inputId = "page_about",
            to = "/about",
            style = JS('({ isActive }) => { return isActive ? { color: "red", textDecoration: "none" } : { textDecoration: "none" }; }'),
            MenuItem(
              "About"
            )
          )
        )
      ),
      Box(
        reactRouter::Routes(
          reactRouter::Route(
            path = "/",
            element = div(
              tags$h1("Home page"),
              tags$h4("A basic example of reactRouter with shinyMaterialUI."),
              uiOutput(outputId = "contentHome")
            )
          ),
          reactRouter::Route(
            path = "/analysis",
            element = div(
              tags$h1("Analysis"),
              uiOutput(outputId = "contentAnalysis")
              )
          ),
          reactRouter::Route(
            path = "/about",
            element = uiOutput(outputId = "contentAbout")
          ),
          reactRouter::Route(path = "*", element = div(tags$p("Error 404")))
        )
      )
    )
    )
  )
)

server <- function(input, output, session) {
  
  # Content for Home page
  output$contentHome <- renderUI({
    p("Content home")
  }) |> 
    shiny::bindEvent("page_home")
  
  # Content for Analysis page
  output$contentAnalysis <- renderUI({
    p("Content analysis")
  }) |> 
    shiny::bindEvent("page_analysis")
  
  # Content for About page
  output$contentAbout <- renderUI({
    div(
      tags$h1("About"),
      p("Content about")
    )
  }) |> 
    shiny::bindEvent("page_about")

}

shinyApp(ui, server)

Example using {shiny.router}

Below an example using the shiny.router R package.

Note that using CssBaseline() at top level doesn’t work with shiny.router. CssBaseline() should be used only at the lower level, as showed below.

library(shiny)
library(shinyMaterialUI)
library(shiny.router)

Header <- CssBaseline(
  Box(
    sx = list(flexGrow = 1),
    AppBar(
      position = "static",
      Toolbar(
        IconButton(
          shiny::icon("home"),
          href = route_link("#!/"),
          size = "large",
          edge = "start",
          color = "inherit",
          'aria-label' = "home",
          sx = list(mr = 2)
        ),
        Link(
          "Other",
          href = route_link("#!/other"),
          underline = "none",
          edge = "start",
          color = "inherit",
          'aria-label' = "other",
          sx = list(mr = 2)
        )
      )
    )
  )
)

Main <- CssBaseline(
  Box(
    sx = list(display = "flex", alignItems = "center", p = 2),
    Typography("Main content.")
  )
)

otherPage <- CssBaseline(
  Box(
    sx = list(display = "flex", alignItems = "center", p = 2),
    Typography("Other content.")
  )
)

ui <- shinyMaterialUIPage( # using CssBaseline() here doesn't work with shiny.router
  Header,
  router_ui(
    route("/", Main),
    route("other", otherPage)
  )
)

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

shinyApp(ui, server)