14

I'm trying to make my Shiny app to redirect the user to another page. I'm using httr to send GET requests and see if the user is logged in. If he's not, I want to redirect him to another link.

Can I do that using R / Shiny only, or do I need some extra libraries?

sample:

library(httr)
library(shiny)
shinyServer(function(input, output) {
rv <- reactiveValues()
rv$mytoken = session$request$token

observeEvent(input$button1, {
  rv$a <- GET("my.url:3405/authtoken", 
              add_headers(
                .headers = c("token" = rv$mytoken)
              ))
  if (rv$a$status_code == 200) {
  } else {
    # redirect magic
  }
})
}

shinyUI(fluidPage(
  actionButton(button1, "btn")
))
vladli
  • 1,454
  • 2
  • 16
  • 40
  • Can you provide sample code with username and password? – Pork Chop Nov 07 '17 at 12:29
  • It's working in a different way: i have auth token in the `session$request` environment, and i check with `GET` if it's the same on the server. So I redirect user based on status code I'm getting in response. I will provide some code if needed – vladli Nov 07 '17 at 12:31
  • You can still provide sample app without it, so when `false` then redirect – Pork Chop Nov 07 '17 at 12:32
  • Is an example sufficient? – vladli Nov 07 '17 at 12:41

2 Answers2

13

Here this will navigate you to google if not true

library(shiny)

jscode <- "Shiny.addCustomMessageHandler('mymessage', function(message) {window.location = 'http://www.google.com';});"

ui <- fluidPage(
  tags$head(tags$script(jscode)),     
  checkboxInput("Redirect","Redirect",value = T)
)

server <- function(input, output, session) {

  observeEvent(input$Redirect,{
    if(!input$Redirect){
      session$sendCustomMessage("mymessage", "mymessage")
    }
  })
}

shinyApp(ui,server)
Pork Chop
  • 28,528
  • 5
  • 63
  • 77
  • As usual, you make it work :)The thing I was looking for, thank you! It seems though that you 'force' it to redirect the user. Doesn't shiny support this behaviour by default? – vladli Nov 07 '17 at 13:01
  • Its easy to do within the `ui` where you can bind buttons and links but you need to send it back the redirect from server and the`shiny` team added the `sendCustomMessage` which is very useful. So just go through it, you will pick it up quite fast – Pork Chop Nov 07 '17 at 13:03
  • have a look at `paste` – Pork Chop Nov 07 '17 at 13:04
  • 1
    Yeah yeah my bad, i'll handle it now. Thanks again. – vladli Nov 07 '17 at 13:05
  • Hi, I don't know if I should create new question - if my app is inside an `iframe` - it seems that it redirects only inside it, and not the whole webpage. Unfortunately, I can't produce any examples here. Do you think by chance there is a way to redirect the whole page to another url, using only shiny? – vladli Nov 09 '17 at 07:53
  • There is an example how to capture click event within an `iframe` by John Harrison, have a look at that and study it, then you will be able to apply to your case. https://stackoverflow.com/questions/46094396/capture-click-within-iframe-in-a-shiny-app/46164975#46164975 – Pork Chop Nov 09 '17 at 08:04
  • 3
    I just used `window.top.location.href` instead of `window.location` and it worked fine. Peace! – vladli Nov 09 '17 at 15:28
  • What if I need to include some reactive value in the url? – Holger Brandl Aug 30 '19 at 10:48
  • Is there no way to do this without JavaScript? Why can't the server side return a 302 response? Also what happens if JavaScript is disabled on client browser in this example? – Kevin Smeeks Jan 07 '22 at 22:41
5

Just to update. There is also an easier way...

shinyjs::runjs(paste0('window.location.href = "...";'))

Don't forget useShinyjs() in UI.

Konrad Stawiski
  • 351
  • 2
  • 10