Labels & Headers

User Interface Headings

Adding labels or headers to a Shiny app is relatively straightforward because these are static elements. This means that they require neither user inputs nor modification by the server into an output. Labels live solely in the UI.

Before we can practice adding labels or headers though, we’ll need to install the package htmltools for convenient header functions. Also, because we are still making a Shiny app, we should confirm that we have the shiny package loaded and ready to go.

Recreating our Reactive App

# install.packages("librarian")
librarian::shelf(shiny, htmltools)

Let’s re-create our reactive app from the previous chapter of the workshop so that we can see how it must be modified to include labels or headers.

First, create the UI:

# Define the UI
label_ui <- fluidPage(
  
  # Create the radio buttons
  numericInput(inputId = "my_input",
               label = "Type a number",
               value = 25),
  
  # And print the output
  "Square root is: ",
  textOutput(outputId = "my_output")
  
  )  

Once we have a UI, we need to define the server to tell the app how to transform the input(s) into output(s).

# Define the server
label_server <- function(input, output){
  
  # Let's take the numeric input and take the square root
  output$my_output <- renderText( sqrt(input$my_input) )
  
}

With both the UI and the server defined, we can re-create our app from the previous chapter by using the shinyApp function:

shinyApp(ui = label_ui, server = label_server)

Excellent; we’ve successfully re-created our first reactive app! Now, let’s leverage the functions in htmltools to add some informative headers to help users navigate our app.

Adding Headers & Line Breaks to our App

As mentioned previously, adding headers is–arguably–one of the more straightforward operations in R Shiny because we need only modify the UI.

Let’s add a top-level header to our app to welcome users to the app and while we’re at it, let’s add smaller headings above the input and output respectively to make the layout of the app clearer.

# Define the UI
label_ui <- fluidPage(
  
  # Add a top-level header
  htmltools::h1("Square Root Calculator"),
  
  # Now add a smaller header for the input
  htmltools::h3("Enter a Number Below"),
  
  # Create the radio buttons
  numericInput(inputId = "my_input",
               label = "Type a number",
               value = 25),
  
  # Also include a smaller header for the output
  htmltools::h3("See Answer Below"),
  
  # And print the output
  "Square root is: ",
  textOutput(outputId = "my_output")
  
  )  

With the UI modified, we can re-create the app (we don’t need to re-define the server because it hasn’t changed)

shinyApp(ui = label_ui, server = label_server)

htmltools supports six levels of header where the function h1 creates the biggest header and h6 creates the smallest. htmltools also allows us to create visual breaks in our app (lines across the page, empty rows, etc.) that can be helpful in de-cluttering the visual presentation of our app.

Let’s add two line breaks beneath the top-level header and one between the numericInput field and the h3 label beneath it.

# Define the UI
label_ui <- fluidPage(
  
  # Add a top-level header
  htmltools::h1("Square Root Calculator"),
  
  # Add two line breaks
  htmltools::hr(),
  htmltools::hr(),

  # Now add a smaller header for the input
  htmltools::h3("Enter a Number Below"),
  
  # Create the radio buttons
  numericInput(inputId = "my_input",
               label = "Type a number",
               value = 25),
  
  # Add a line break
  htmltools::hr(),
  
  # Also include a smaller header for the output
  htmltools::h3("See Answer Below"),
  
  # And print the output
  "Square root is: ",
  textOutput(outputId = "my_output")
  
  )  

And re-create the app to see the update.

shinyApp(ui = label_ui, server = label_server)

Adding Labels to our App

Labels are simpler to add to a Shiny app than headers because they are essentially plain text. Technically, the text in our app “Square root is:” is a label!

To showcase this further though, we can add a label above the double line break explaining what this app does to future users. For simplicity’s sake, we can create the app and the new UI in the same code chunk below.

# Define the UI
label_ui <- fluidPage(
  
  # Add a top-level header
  htmltools::h1("Square Root Calculator"),
  
  # Add an app explanation as a label
  "Welcome! This app takes the square root of any number that you type into the box below (by using the R function 'sqrt').",
  
  # Add two line breaks
  htmltools::hr(),
  htmltools::hr(),

  # Now add a smaller header for the input
  htmltools::h3("Enter a Number Below"),
  
  # Create the radio buttons
  numericInput(inputId = "my_input",
               label = "Type a number",
               value = 25),
  
  # Add a line break
  htmltools::hr(),
  
  # Also include a smaller header for the output
  htmltools::h3("See Answer Below"),
  
  # And print the output
  "Square root is: ",
  textOutput(outputId = "my_output")
  
  )

# And re-create the app
shinyApp(ui = label_ui, server = label_server)

Customizing Text

While we are on the subject of adding headers and labels we can also discuss how text formatting (e.g., bold, code, italic, etc.) can be implemented in a Shiny app.

For these operations we’ll return to htmltools. To show this, let’s make “Welcome!” bold, and put the R function sqrt in “code” font (i.e., how it appears here!).

# Define the UI
label_ui <- fluidPage(
  
  # Add a top-level header
  htmltools::h1("Square Root Calculator"),
  
  # Add an app explanation as a label
  ## Put "Welcome" in bold
  htmltools::strong("Welcome!"),
  ## Keep plain text in the label
  "This app takes the square root of any number that you type into the box below (by using the R function ",
  ## Make the function name "code formatted"
  htmltools::code("sqrt"),
  ## Close the sentence's parentheses in plain text
  ").",
  
  # Add two line breaks
  htmltools::hr(),
  htmltools::hr(),

  # Now add a smaller header for the input
  htmltools::h3("Enter a Number Below"),
  
  # Create the radio buttons
  numericInput(inputId = "my_input",
               label = "Type a number",
               value = 25),
  
  # Add a line break
  htmltools::hr(),
  
  # Also include a smaller header for the output
  htmltools::h3("See Answer Below"),
  
  # And print the output
  "Square root is: ",
  textOutput(outputId = "my_output")
  
  )

# And re-create the app
shinyApp(ui = label_ui, server = label_server)

As demonstrated above the strong function makes the text inside of it bold while the code function makes its text in ‘code style’.

Nesting Label Functions

As with typical R functions, Shiny let’s you ‘nest’ functions around each other to apply multiple text-modifying effects to the same text.

In our app the welcome message is good but the font is a little small. Let’s make it a header but keep it smaller than our sub-headings for the input and output of the app.

# Define the UI
label_ui <- fluidPage(
  
  # Add a top-level header
  htmltools::h1("Square Root Calculator"),
  
  # Add an app explanation as a small(ish) header
  htmltools::h4(
    ## Put "Welcome" in bold
  htmltools::strong("Welcome!"),
  ## Keep plain text in the label
  "This app takes the square root of any number that you type into the box below (by using the R function ",
  ## Make the function name "code formatted"
  htmltools::code("sqrt"),
  ## Close the sentence's parentheses in plain text
  ")."
  ),
  
  # Add two line breaks
  htmltools::hr(),
  htmltools::hr(),

  # Now add a smaller header for the input
  htmltools::h3("Enter a Number Below"),
  
  # Create the radio buttons
  numericInput(inputId = "my_input",
               label = "Type a number",
               value = 25),
  
  # Add a line break
  htmltools::hr(),
  
  # Also include a smaller header for the output
  htmltools::h3("See Answer Below"),
  
  # And print the output
  "Square root is: ",
  textOutput(outputId = "my_output")
  
  )

# And re-create the app
shinyApp(ui = label_ui, server = label_server)

Great! By leveraging labels, headers, text customization, and line breaks we have started to create a visually-appealing and easily-navigable Shiny app!

Let’s move on to experimenting with Shiny’s built-in app layouts.