---

This site uses cookies. Read more.

 24 November, 2020

Basic Routing for Shiny Web Applications

Web applications couldn’t exist without routing. Think about it in terms of the Appsilon website – you’ve visited our home page, navigated to the blog, and opened this particular article. That’s routing in a nutshell – matching UI components to a URL.

Appsilon released the open source shiny.router package back in late 2018, and just recently version 0.2.0 went live on CRAN. This version fixed some bugs, augmented existing functionality a bit, and made a few important changes. In this article, we’ll walk you through the version 0.2.0 update and show you how to create navbars using shiny.router. 

You can download the source code for this article here.

To learn more about Appsilon’s open source packages, see our new Open Source Landing Page: 

Appsilon's shiny.tools landing page for our open source packages.

Appsilon’s shiny.tools landing page for our open source packages.

Introducing shiny.router

At Appsilon, we routinely build Shiny applications for Global 2000 companies. The problem of routing is one of the first ones we encounter on every project. It made sense to develop an open-source package that handles it with ease. After all, routing is a common component of any web application and behaves identically in most projects.

Displaying the app’s content on multiple pages can be achieved via tabsets, subpages of a dashboard. There was no easy way to direct users to a specific subpage via URL for a long time. Recently some alternative solutions started to emerge, but the shiny.router remains the easiest one.

We have used shiny.router in many commercial projects, so we can confirm it is a field-tested solution. Also, many large organizations have adopted it as a solution on their own.

The latest version of the package is available on CRAN, so the installation couldn’t be any easier:

install.packages("shiny.router")

The new version (0.2.0) was released on the 30th October 2020, and it brought new documentation and functionalities and fixed existing issues. You can read the full changelog here.

See some impressive Example Shiny Apps in our Shiny Demo Gallery

Creating Navigation Bars with shiny.router

To show how shiny.router works in practice, we’ll develop a simple dashboard with a couple of routes. Every route will have a dummy text, showing us which route we’re on.

To start, we’ll import both shiny and shiny.router:

library(shiny)
library(shiny.router)

Next, we will store content for three pages in three variables. Every page has a shiny.titlePanel and a paragraph:

home_page <- div(
  titlePanel("Dashboard"),
  p("This is a dashboard page")
)

settings_page <- div(
  titlePanel("Settings"),
  p("This is a settings page")
)

contact_page <- div(
  titlePanel("Contact"),
  p("This is a contact page")
)

We can then make a router and attach each of the pages with its corresponding route. The dashboard is located on the root page, so it will be the first one you see:

router <- make_router(
  route("/", home_page),
  route("settings", settings_page),
  route("contact", contact_page)
)

The rest of the Shiny app is more or less what you would expect. We have to declare the UI, which contains a list of routes that enable us to navigate between pages. The server function passes input, output, and session data to the router. Finally, the call to shinyApp brings these two components together.

ui <- fluidPage(
  tags$ul(
    tags$li(a(href = route_link("/"), "Dashboard")),
    tags$li(a(href = route_link("settings"), "Settings")),
    tags$li(a(href = route_link("contact"), "Contact"))
  ),
  router$ui
)

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

shinyApp(ui, server)

As a result, we have the following web application:

Unstyled Shiny Router App

Unstyled Shiny Router App

The application gets the job done but is quite basic with regards to the styling. Let’s fix that next.

Styling Navigation Bars

You can add styles to your Shiny applications with CSS. To do so, create a www folder where your R script is, and create a CSS file inside it. We’ve named ours main.css, but you can call yours whatever you want.

To link the created CSS file with the Shiny app, we have to add a theme to shiny.fluidPage. Here’s how:

ui <- fluidPage(
  theme = "main.css",
  tags$ul(
    tags$li(a(href = route_link("/"), "Dashboard")),
    tags$li(a(href = route_link("settings"), "Settings")),
    tags$li(a(href = route_link("contact"), "Contact"))
  ),
  router$ui
)

The value for the theme parameter must be identical to the name of the CSS file. 

If you were to run the app now, everything would look the same as before. That’s because we haven’t added any stylings yet. Copy the following code snippet to your CSS file:

ul {
  background-color: #0099f9;
    display: flex;
  justify-content: flex-end;
  list-style-type: none;
}

ul li a {
  color: #ffffff;
    display: block;
  font-size: 1.6rem;
  padding: 1.5rem 1.6rem;
  text-decoration: none;
  transition: all, 0.1s;
}

a:link, a:visited, a:hover, a:active {
  color: #ffffff;
    text-decoration: none;
}

ul li a:hover {
  background-color: #1589d1;
    color: #ffffff;
}

Save and rerun the application. You will see the following:

Styled Shiny Router App

Styled Shiny Router App

And that’s how you can style shiny.router and Shiny apps in general.

Conclusion

In this short hands-on guide, we’ve covered the intuition and logic behind the shiny.router package. We’ve seen how routing works, how to create navigation bars with routing, and how to style navigation bars.

You can learn more about shiny.router and other Appsilon’s open-source packages below:

Appsilon is hiring! We are primarily seeking a senior-level engineering manager who can mentor our junior developers. See our Careers page for all new openings, including openings for a Project Manager and Community Manager.



Reach out to Appsilon

Maria Grycuk
Maria Grycuk
Project Manager