R Shiny bslib - How to Work With Bootstrap Themes in Shiny
R Shiny bslib is a package that makes working with Bootstrap themes a breeze. Let's face it - Shiny apps look dull and mainstream by default. Not everyone has a keen eye for design, and sometimes spending days or weeks playing around with CSS isn't an option. You need something that will look better, or at least brandable right now. If that sounds like you, look no further than Bootstrap and <code>bslib</code>. Today you'll learn all about it, from the basics to creating custom themes for R Shiny applications. <blockquote>Could your Shiny app benefit from a little CSS? Here's how to use <a href="https://appsilon.com/how-to-use-tailwindcss-in-shiny/" target="_blank" rel="noopener">TailwindCSS in R Shiny</a>.</blockquote> Table of contents: <ul><li><a href="#introduction">What is Bootstrap and R Shiny bslib?</a></li><li><a href="#make-themes">How to Make Bootstrap Themes with R Shiny bslib</a></li><li><a href="#shiny">How to Add Bootstrap Themes to R Shiny</a></li><li><a href="#summary">Summary of R Shiny bslib</a></li></ul> <hr /> <h2 id="introduction">What is Bootstrap and R Shiny bslib?</h2> In the most simple terms, Bootstrap is a free and open-source web development framework. It enables you to make responsive and mobile-first websites and apps with ease. Bootstrap provides a collection of styles you can use out of the box. For example, once you have Bootstrap configured, you only need to assign <code>class</code> attributes to HTML elements in order for styles to apply. <b>So, why would you want that?</b> By using a prebuilt CSS framework, you can save hours, days, or even weeks by not writing the entire application style from scratch. Bootstrap is easy to use and comes with a predefined grid system, so your website will be responsive and mobile-friendly immediately (read: less or no media queries). Now, Bootstrap isn't a be-all-end-all solution. It provides you with everything you need to get started, but you should still know how to change colors, fonts, and others by yourself. When it comes to R and R Shiny, you have two options if you want to use Bootstrap. You can either download the framework and embed it into your app, or you can use an R package such as <code>bslib</code> to do most of the heavy lifting for you. <b>But what is <code>bslib</code>?</b> This R package provides tools for customizing Bootstrap themes directly in R, and it primarily targets Shiny apps and R Markdown documents. To use it, you'll first need to install it: <pre><code class="language-r">install.packages("bslib")</code></pre> Let's see how you can use <code>bslib</code> next. <h2 id="make-themes">How to Make Bootstrap Themes with R Shiny bslib</h2> What's neat about <code>bslib</code> is that you don't have to download any specific version of Bootstrap manually - you can specify versions 3, 4, or 5 straight from R. To get your hands dirty with your first theme, simply store the results of a <code>bs_theme()</code> function call to a variable. The only parameter we'll specify for now is <code>version</code>, and we'll set it to <code>5</code>. It instructs <code>bslib</code> to use the latest version of Bootstrap, or Bootstrap 5: <pre><code class="language-r">library(bslib) <br>first_bs5_theme <- bs_theme( version = 5 ) first_bs5_theme </code></pre> Here are the contents of <code>first_bs5_theme</code>: <img class="size-full wp-image-13385" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d355e407a924913e3720_b3b73908_1-2.webp" alt="Image 1 - Contents of a variable containing a Bootstrap theme" width="1978" height="690" /> Image 1 - Contents of a variable containing a Bootstrap theme This doesn't tell us much, sure. It would be a lot nicer to preview the theme. The <code>bs_theme_preview()</code> function will create a boilerplate R Shiny bslib application around your theme. That app will showcase most of the Bootstrap elements that are relevant to R Shiny. For now, we'll also set <code>with_themer = FALSE</code> to avoid extra confusion - it will be covered and explained later: <pre><code class="language-r">library(bslib) <br>first_bs5_theme <- bs_theme( version = 5 ) bs_theme_preview(theme = first_bs5_theme, with_themer = FALSE) </code></pre> Below are a couple of images from the first three tabs of the Shiny app: <img class="size-full wp-image-13387" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d356d39529106a3fbd09_f52cca74_2-2.webp" alt=""<yoastmark" /> <img class="size-full wp-image-13389" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d356003913ca45eb0f9c_b63803c7_3-2.webp" alt=""<yoastmark" /> <img class="size-full wp-image-13391" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d35729f75851d3d06d3c_a31bd8b5_4-2.webp" alt=""<yoastmark" /> Neat, right? That's one way to style your R Shiny applications, but the story doesn't end here. There are many parameters you can pass to <code>bs_theme()</code>, and you can grab the full list in the <a href="https://rstudio.github.io/bslib/reference/bs_theme.html" target="_blank" rel="nofollow noopener">official documentation</a>. For demonstration, we'll show you how to modify background, foreground, primary, and secondary colors, and also how to change the base font of the theme: <pre><code class="language-r">library(bslib) <br>custom_theme <- bs_theme( version = 5, bg = "#FFFFFF", fg = "#000000", primary = "#0199F8", secondary = "#FF374B", base_font = "Maven Pro" ) bs_theme_preview(theme = custom_theme, with_themer = FALSE)</code></pre> The <i>Fonts</i> tab of the preview application best demonstrates how the styles were tweaked: <img class="size-full wp-image-13393" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d35893029c937a7f70a9_3efe5686_5-2.webp" alt="Image 5 - Example Shiny app with custom font and colors" width="2710" height="2188" /> Image 5 - Example Shiny app with custom font and colors Now we're getting somewhere. You know how to use <code>bslib</code> to create custom themes, but there's still one important question to answer - <b>How can you add custom Bootstrap themes to your R Shiny apps?</b> Let's answer that next. <h2 id="shiny">How to Add Bootstrap Themes to R Shiny</h2> To keep things to the point, we'll borrow the R Shiny app code from our <a href="https://appsilon.com/monitoring-r-shiny-user-adoption/" target="_blank" rel="noopener">Top 3 Tools to Monitor User Adoption in R Shiny</a> article. It lets you specify columns of the Iris dataset on which then a clustering algorithm is applied: <pre><code class="language-r">library(shiny) <br> ui <- fluidPage( headerPanel("Iris k-means clustering"), sidebarLayout( sidebarPanel( selectInput( inputId = "xcol", label = "X Variable", choices = names(iris) ), selectInput( inputId = "ycol", label = "Y Variable", choices = names(iris), selected = names(iris)[[2]] ), numericInput( inputId = "clusters", label = "Cluster count", value = 3, min = 1, max = 9 ) ), mainPanel( plotOutput("plot1") ) ) ) <br> server <- function(input, output, session) { selectedData <- reactive({ iris[, c(input$xcol, input$ycol)] }) clusters <- reactive({ kmeans(selectedData(), input$clusters) }) output$plot1 <- renderPlot({ palette(c( "#E41A1C", "#377EB8", "#4DAF4A", "#984EA3", "#FF7F00", "#FFFF33", "#A65628", "#F781BF", "#999999" )) par(mar = c(5.1, 4.1, 0, 1)) plot(selectedData(), col = clusters()$cluster, pch = 20, cex = 3 ) points(clusters()$centers, pch = 4, cex = 4, lwd = 4) }) } <br> shinyApp(ui = ui, server = server)</code></pre> If you're wondering, here's how the app looks: <img class="size-full wp-image-13395" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d3595591af1433a8dd01_e812d1e0_6-2.webp" alt="Image 6 - Basic R Shiny clustering app" width="2258" height="1786" /> Image 6 - Basic R Shiny clustering app To add a custom Bootstrap theme, you'll have to: <ol><li>Import the <code>bslib</code> package.</li><li>Add the code for your theme (<code>custom_theme</code>).</li><li>Add a <code>theme</code> argument to Shiny UI.</li><li>Wrap <code>shinyApp(ui = ui, server = server)</code> with another function - <code>run_with_themer().</code></li></ol> That's all! Below is the full source code if you got lost in the process: <pre><code class="language-r">library(shiny) library(bslib) <br>custom_theme <- bs_theme( version = 5, bg = "#FFFFFF", fg = "#000000", primary = "#0199F8", secondary = "#FF374B", base_font = "Maven Pro" ) <br>ui <- fluidPage( theme = custom_theme, headerPanel("Iris k-means clustering"), sidebarLayout( sidebarPanel( selectInput( inputId = "xcol", label = "X Variable", choices = names(iris) ), selectInput( inputId = "ycol", label = "Y Variable", choices = names(iris), selected = names(iris)[[2]] ), numericInput( inputId = "clusters", label = "Cluster count", value = 3, min = 1, max = 9 ) ), mainPanel( plotOutput("plot1") ) ) ) <br> server <- function(input, output, session) { selectedData <- reactive({ iris[, c(input$xcol, input$ycol)] }) clusters <- reactive({ kmeans(selectedData(), input$clusters) }) output$plot1 <- renderPlot({ palette(c( "#E41A1C", "#377EB8", "#4DAF4A", "#984EA3", "#FF7F00", "#FFFF33", "#A65628", "#F781BF", "#999999" )) par(mar = c(5.1, 4.1, 0, 1)) plot(selectedData(), col = clusters()$cluster, pch = 20, cex = 3 ) points(clusters()$centers, pch = 4, cex = 4, lwd = 4) }) } <br> run_with_themer(shinyApp(ui = ui, server = server))</code></pre> The themed Shiny app looks like this: <img class="size-full wp-image-13397" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d35af87028844767cbb4_67d74b6f_7-1.webp" alt="Image 7 - Themed R Shiny clustering app" width="2650" height="2076" /> Image 7 - Themed R Shiny clustering app You can notice how we didn't specify <code>with_themer = FALSE</code> this time. Because of that, you can tweak the theme parameters on the fly. For example, you can change the <i>Overall theme</i> from <i>Default</i> to <i>Darkly</i>: <img class="size-full wp-image-13399" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d35beb1c1eedd364aa81_8be0600d_8-1.webp" alt="Image 8 - Changing the overall theme" width="2650" height="2076" /> Image 8 - Changing the overall theme The best way to see the theme was changed is in the text. We're using <i>Maven Pro</i> for all textual elements, which is noticeable if you expand the dropdown menu: <img class="size-full wp-image-13401" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b7d35c7a1cb06c0305aff5_02e763f9_9.webp" alt="Image 9 - Examining the app font" width="2650" height="2076" /> Image 9 - Examining the app font And that's everything you need to use R Shiny bslib. There are many other theme parameters you can change, but we'll leave the exploration up to you. <hr /> <h2 id="summary">Summary of R Shiny bslib</h2> Today you've learned how to work with Bootstrap 5 themes in R Shiny, and how to customize these themes straight from R. There's no need to download Bootstrap CSS/JS files and embed them into your dashboard, as this package does everything for you. Using and customizing a theme boils down to adding a couple of additional function calls to your existing R Shiny dashboard. It's that simple. Now it's time for you to shine. For a homework assignment, we recommend you research and use other <code>bs_theme()</code> parameters and come up with a fully-customized theme. Give it a go, and make sure to share your before/after shots with us on Twitter - <a href="https://twitter.com/appsilon" target="_blank" rel="noopener">@appsilon</a>. We'd love to see what you come up with. <blockquote>Looking for an inspiration for your next R Shiny project? <a href="https://appsilon.com/r-shiny-in-life-sciences-examples/" target="_blank" rel="noopener">Take a look at these 7 examples of R Shiny dashboards in life sciences</a>.</blockquote>