Site icon R-bloggers

Adding Shiny app’apos;s parameters to the URL

[This article was first published on https://pacha.dev/blog, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
< !DOCTYPE html> < charset="utf-8"> < http-equiv="X-UA-Compatible" content="IE=edge"> < name="viewport" content="width=device-width, initial-scale=1.0"> pacha.dev/blog < !-- MathJax Configuration --> < !-- Smart header: libraries detected based on content --> < !-- File: /tmp/tmp.KG8o8Brrgt/index.html -->
  • < !-- DEBUG: Found sourceCode --> < !-- Load custom CSS after any library CSS to ensure proper precedence -->
  • < header class="site-top">

    Mauricio “Pachá” Vargas Sepúlveda

    Blog with notes about R, Shiny, SQL, Python, Linux and C++. This blog is listed on R-Bloggers.

    HOME 🏠
    < !-- categories are printed below this--> < nav class="sidebar-nav">

    Categories

    < header id="title-block-header" class="quarto-title-block default">

    Adding Shiny app’s parameters to the URL

    Modify the URL from Shiny UI elements and viceversa
    Author

    Mauricio “Pachá” Vargas S.

    Published

    August 10, 2025

    Shiny allows to use all of R to visualize information, no matter if it is a sophisticated statistical model or a simple plot. One of the features it does not provide out-of-the-box is adding the selected parameters to the URL, like this:

    https://pacha.dev/palmerpenguinsshiny?inputs&species="Adelie"&island="Torgersen"

    In order to have this type of URL I shall demonstrate a simple case with golem. Let’s start by creating a project:

    golem::create_golem("palmerpenguinsshiny")

    Open R/run_app.R and change enableBookmarking = NULL to enableBookmarking = "url".

    Open R/app_server.R and add these lines at the end of app_server():

    # Bookmarking ----
    
    observe({
        # Trigger this observer every time an input changes
        # strip shiny related URL parameters
        shiny::reactiveValuesToList(input)
        setBookmarkExclude(c(
            "parameter_not_in_url"
        ))
        session$doBookmark()
    })
    
    onBookmarked(function(url) {
        updateQueryString(url)
    })

    Now we need to add contents to the app. Let’s create an app that allows the user to filter by species and island to obtain a plot of the body mass distribution.

    Here’s a shortcut to simplify things and use the pipe operator:

    usethis::use_pipe()
    devtools::document()

    Create a copy of the data we need:

    penguins_sib <- palmerpenguins::penguins[, c("species", "island", "body_mass_g")]
    usethis::use_data(penguins_sib)

    Now let’s add contents to app_server(), like this:

    #' The application server-side
    #'
    #' @param input,output,session Internal parameters for {shiny}.
    #'     DO NOT REMOVE.
    #' @import shiny
    #' @import ggplot2
    #' @importFrom dplyr filter
    #'
    #' @noRd
    app_server <- function(input, output, session) {
      # Main plot ----
    
      # Filter by species and island, then show the distribution of body_mass_g
      output$main_plot <- renderPlot({
        req(input$species, input$island)
        penguins_sib %>%
          filter(
            species %in% input$species,
            island %in% input$island
          ) %>%
          ggplot(aes(x = body_mass_g)) +
          geom_histogram(bins = input$bins, fill = input$fill, color = "black") +
          labs(
            title = "Distribution of Body Mass (g)",
            x = "Body Mass (g)",
            y = "Count"
          ) +
          theme_minimal(base_size = 13)
      })
    
      # Bookmarking ----
    
      observe({
        # Trigger this observer every time an input changes
        # strip shiny related URL parameters
        shiny::reactiveValuesToList(input)
        setBookmarkExclude(c(
          "fill"
        ))
        session$doBookmark()
      })
    
      onBookmarked(function(url) {
        updateQueryString(url)
      })
    }

    Pass the server logic on UI side:

    #' The application User-Interface
    #'
    #' @param request Internal parameter for `{shiny}`.
    #'     DO NOT REMOVE.
    #' @import shiny
    #' @noRd
    app_ui <- function(request) {
      tagList(
        # Leave this function for adding external resources
        golem_add_external_resources(),
        # Your application UI logic
        
        # Filters
    
        sidebarLayout(
          sidebarPanel(
            selectInput("species", "Select Species:", choices = unique(penguins$species), multiple = TRUE),
            selectInput("island", "Select Island:", choices = unique(penguins$island), multiple = TRUE),
            selectInput("fill", "Select Fill Color:", choices = c("#3d809d", "#d04e66", "#365158"),
              multiple = FALSE, selected = "#3d809d"),
            sliderInput("bins", "Number of Bins:", min = 1, max = 50, value = 30)
          ),
          mainPanel(
            plotOutput("main_plot")
          )
        )
      )
    }
    
    #' Add external Resources to the Application
    #'
    #' This function is internally used to add external
    #' resources inside the Shiny application.
    #'
    #' @import shiny
    #' @importFrom golem add_resource_path activate_js favicon bundle_resources
    #' @noRd
    golem_add_external_resources <- function() {
      add_resource_path(
        "www",
        app_sys("app/www")
      )
    
      tags$head(
        favicon(),
        bundle_resources(
          path = app_sys("app/www"),
          app_title = "palmerpenguins"
        )
        # Add here other external resources
        # for example, you can add shinyalert::useShinyalert()
      )
    }

    Now run:

    devtools::load_all()
    run_app()

    You should see your app running locally, and when you select the two required fields (species and island) there will be a rendered plot and a URL of the form:

    http://127.0.0.1:6736/?_inputs_&species=%22Adelie%22&island=%22Biscoe%22&bins=30

    Note that the fill colour is not in the URL but that is intentional 🙂

    The full code is here: https://github.com/pachadotdev/palmerpenguinsshiny.

    Don’t forget to add a license to your app (e.g., open dev/01_start.R to select the MIT license, or use Apache with usethis::use_apache_license()).

    If this resource was useful to you, please consider donating here: https://buymeacoffee.com/pacha.

    < footer>

    Loading…

  • < !-- Load shared sidebar -->
    To leave a comment for the author, please follow the link and comment on their blog: https://pacha.dev/blog.

    R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
    Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
    Exit mobile version