44

In web browsers you pass parameters to a website like

www.mysite.com/?parameter=1

I have a shiny app and I would like to use the parameter passed in to the site in calculations as an input. So is it possible to do something like www.mysite.com/?parameter=1 and then use input!parameter?

Can you provide any sample code or links?

Thank you

user3022875
  • 8,598
  • 26
  • 103
  • 167
  • See also [bookmarking state](http://shiny.rstudio.com/articles/bookmarking-state.html) on the shiny website (seen in [this SO Answer](https://stackoverflow.com/a/25385474/2641825)). It enables you to use urls of the form: https://gallery.shinyapps.io/113-bookmarking-url/?_inputs_&n=149. – Paul Rougieux Feb 20 '18 at 13:49
  • 1
    For future readers: [Here](https://stackoverflow.com/questions/70080803/uri-routing-for-shinydashboard-using-shiny-router/70093686#70093686) you can find a related post showing different approaches on uri routing for `shinydashboard`. – ismirsehregal Jan 25 '22 at 15:07

4 Answers4

60

You'd have to update the input yourself when the app initializes based on the URL. You would use the session$clientData$url_search variable to get the query parameters. Here's an example, you can easily expand this into your needs

library(shiny)

shinyApp(
  ui = fluidPage(
    textInput("text", "Text", "")
  ),
  server = function(input, output, session) {
    observe({
      query <- parseQueryString(session$clientData$url_search)
      if (!is.null(query[['text']])) {
        updateTextInput(session, "text", value = query[['text']])
      }
    })
  }
)
DeanAttali
  • 25,268
  • 10
  • 92
  • 118
  • Is it possible to update the input directly on the app? I'm trying to but it automatically changes to the url value. Eg in url I choose text='abc' and then on the app I want to define text='def'. – hsilva Aug 31 '17 at 09:12
  • And how would you do this without having to put an input in the UI? People may not want the user messing with the values that were passed. – randy Aug 15 '18 at 00:08
  • The input is just a demonstration of what you can do with the parameter. It's absolutely not required – DeanAttali Sep 21 '18 at 23:51
19

Building off of daattali, this takes any number of inputs and does the assigning of values for you for a few different types of inputs:

ui.R:

library(shiny)

shinyUI(fluidPage(
textInput("symbol", "Symbol Entry", ""),

dateInput("date_start", h4("Start Date"), value = "2005-01-01" ,startview = "year"),

selectInput("period_select", label = h4("Frequency of Updates"),
            c("Monthly" = 1,
              "Quarterly" = 2,
              "Weekly" = 3,
              "Daily" = 4)),

sliderInput("smaLen", label = "SMA Len",min = 1, max = 200, value = 115),br(),

checkboxInput("usema", "Use MA", FALSE)

))

server.R:

shinyServer(function(input, output,session) {
observe({
 query <- parseQueryString(session$clientData$url_search)

 for (i in 1:(length(reactiveValuesToList(input)))) {
  nameval = names(reactiveValuesToList(input)[i])
  valuetoupdate = query[[nameval]]

  if (!is.null(query[[nameval]])) {
    if (is.na(as.numeric(valuetoupdate))) {
      updateTextInput(session, nameval, value = valuetoupdate)
    }
    else {
      updateTextInput(session, nameval, value = as.numeric(valuetoupdate))
    }
  }

 }

 })
})

Example URL to test: 127.0.0.1:5767/?symbol=BBB,AAA,CCC,DDD&date_start=2005-01-02&period_select=2&smaLen=153&usema=1

Jason S
  • 199
  • 2
  • 2
  • 1
    Hi Jason, I am trying to something similiar to pass two arguments to updateselectinput, but no success until now, https://stackoverflow.com/questions/65520716/how-pass-multiple-parameters-to-shiny-app-via-url-to-updateselectinput – Andrew Dec 31 '20 at 13:09
  • Hello Jason, this answer is not generic enough to update anything other than `textInput` (since only `updateTextInput` is used). Also the multi-parameter to single input case given is not handled (parameter `symbol` in the example URL, see also question of Andrew in comment). – faidherbard Oct 23 '22 at 15:23
4

Shiny App: How to Pass Multiple Tokens/Parameters through URL

The standard delimeter for tokens passed through url to shiny app is the & symbol.

Example shiny app code:

server <- function(input, output, session) {
  observe({
    query <- parseQueryString(session$clientData$url_search)
    if (!is.null(query[['paramA']])) {
        updateTextInput(session, "InputLabel_A", value = query[['paramA']])
    }
    if (!is.null(query[['paramB']])) {
        updateTextInput(session, "InputLabel_A", value = query[['paramB']])
    }
  })
  # ... R code that makes your app produce output ..
}

Coresponding URL example: http://localhost.com/?paramA=hello&?paramB=world

Reference: parseQueryString Docs

Jake
  • 106
  • 4
1

Building off DeanAttali's idea, this snippet will re-generate the URL at the top so that users can copy the link for sharing to others.

The stringr:: part can probably be enhanced to be more URL-friendly.

library(stringr)
library(glue)
library(shiny)

# http://127.0.0.1:8080/?text=hello+world+I%27m+a+shiny+app
shinyApp(
    ui = fluidPage(
        textOutput("url"),
        textInput("text", "Text", ""),
    ),
    server = function(input, output, session) {
        observe({
            query <- parseQueryString(session$clientData$url_search)
            if (!is.null(query[['text']])) {
                updateTextInput(session, "text", value = query[['text']])
            }
        })
        
        output$url <- renderText({
            stringr::str_replace_all(glue::glue("http://127.0.0.1:8080/?text={input$text}"), ' ', '+')
                
        })
    },
    options=list(port=8080)
)
RAFisherman
  • 889
  • 1
  • 8
  • 9