3

I need to put an automatic redirect to a different link in an R Markdown app with Shiny runtime. I tried several approaches but none works for me. (They work fine in Shiny but not in R Markdown).

How can I make my R Markdown app redirect the user to another page?


Here's a list of things I tried.

This solution: Redirect in Shiny app works in Shiny, but I couldn't get it to work in R Markdown.

This solution, again, works in Shiny but fails in R Markdown:

---
title: "Untitled"
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: fill
runtime: shiny
---


```{r redirect}
    singleton(tags$head(tags$script('window.location.replace("https://stackoverflow.com");')))

```

I also tried shinyjs approach, based on How do I redirect to another webpage?, which works fine in Shiny but not in R Markdown:

```{r redirect_lab}
library(shinyjs)
useShinyjs(rmd = TRUE)

##both fail in Rmd
runjs('window.location.replace("https://stackoverflow.com");')
# runjs('window.location.href = "https://stackoverflow.com";')
```

I also tried a hacky approach that creates a link, ties it to a button and then programmatically clicks the button using shinyjs: How to select a specific tab in R Markdown?

```{r redirect_lab}
library(shinyjs)
useShinyjs(rmd = TRUE) 

tags$a(href = "https://stackoverflow.com",
  # set this button to `display: none;` but *not* to `hidden`
  shiny::actionButton("btn2", "redirect"
                      # , style = "display: none"
                      )
)
click("btn2")

```

Strangely when the R Markdown page loads it does not redirect automatically. But if I click the button manually with the mouse, then it will redirect to the link. But I'm stumped why this would not work programmatically.

landroni
  • 2,902
  • 1
  • 32
  • 39
  • The reason your solution is not working is because your `click` call happens outside of the reactive shiny environment, and is not guaranteed to happen after the page has loaded (so the button may not exist yet when the function is called). In a pure javascript page, this is taken care of by the `$(document).ready({})` callback. – All Downhill From Here Aug 22 '21 at 14:07

2 Answers2

2

We can add <meta> tags to the HTML header and trigger a redirect via

<meta http-equiv="refresh" content="0; url=http://www.stackoverflow.com/"/>'

Note that this is working in the browser, but not in the RStudio Viewer.

---
title: "Untitled"
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: fill
    includes:
      in_header: myheader.html
runtime: shiny
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE )

fileConn <- file("myheader.html")
writeLines('<meta http-equiv="refresh" content="0; url=http://www.stackoverflow.com/"/>', fileConn)
close(fileConn)
```
TimTeaFan
  • 17,549
  • 4
  • 18
  • 39
1

A simple solution I found was to directly include a redirect javascript as an explicit <script> in the markdown, and either trigger is as direct event, or as an explicit js call.

#Option one: direct link to JS event
<script type="text/javascript">
    document.getElementById("myButton").onclick = function () {
        location.href = "http://www.google.com";
    };
</script>

```{r, echo=F}
actionButton("myButton", "Redirect")
```

#Option two: dedicate redirect js, triggered by shinyjs
<script type="text/javascript">
    go_away = function () {
        location.href = "http://www.google.com";
    };
</script> 

```{r, echo=F}
shinyjs::useShinyjs(rmd = TRUE)
actionButton("myButton2", "Redirect!!")

observeEvent(input$myButton2, {
  shinyjs::runjs('go_away()')
})

```

The first option works since r Markdown/Shiny explicitly creates input elements by ID. For less hacky second option, the function can also be called explicitly from the runjs call.

  • Not sure why, but neither of these options worked for me. Are you doing something special in the Rmd header? – landroni Aug 24 '21 at 16:20