Can't embed public shinyapps.io app in RMarkdown with HTML output (without runtime:shiny)

Hi community!

I am trying to embed a public Shiny app that is hosted on shinyapps.io as an iframe into a RMarkdown document with HTML output . I see some basic components of the Shinyapp in the iframe, but the CSS does not work and there is no functionality (first screenshot).

I tried two different ways to embed the app, both with the same result: First I tried to embed the app directly as an iframe, second I tried using knitr::include_app.

Both tests are included in this test .Rmd file:
(I replaced the R code chunk three ticks (```) with only one tick (`) to get the code to be displayed correctly here on the forum.)

---
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## Test 1: Manual embedding with `iframe` tag

<iframe width="100%" height="150px" src="https://snsf-open.shinyapps.io/shiny_demoapp/" title="Shinyapps.io iframe demo"></iframe>

## Test 2: Automatic embedding with `knitr::include_app`

```{r test}
knitr::include_app(url = "https://snsf-open.shinyapps.io/shiny_demoapp/", height = "150px")
```

The the knitted .Rmd produced the following HTML, not showing any CSS or buttons of the Shinyapp:

When I add runtime: shiny in the YAML header, it does work. But I don't want to do this, as the output should be a standalone HTML file that can run on every webhost, not something I have to deploy on an RStudio Connect server.

I don't get why this simple embedding of an iframe does not work, especially as it works if I try if with an HTML file:

Test

``` This HTML displays correctly in a browser:

Thank you for any responses.

it looks like you are just missing ticks (`)

change

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

to

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

etc. and it seems to work fine

as to why... I would guess it is down to the markdown parsing engine; (`) indicating code not to be run in the browser (presented in monospaced type), and ( ```{r}...```)
indicating a chunk of code to be and the language to run it in

Hi antdurrant, thank you for your answer! Sorry, this was a bit misleading from my side. I just replaced the three ticks with only one to make the .Rmd file display correctly here on the RStudio community forum. I wanted to display the whole .Rmd file inside the post, but when I use the original three ticks for demarking code chunks, this interferes with the code annotation feature here on the forum. My problem is not that this code does not run, it does, but the output is not the expected one (iframes in the first screenshot).

I see! markdown is actually clever enough that you can do it with extra ticks and it will render right

```{r}
# this is four ticks, new line, three ticks
# comment
# three ticks, new line, four ticks
```

But for the question at hand...
I think what you are experiencing is a failure of the html rendering engine inside of RStudio - it is okay but definitely not actually a modern web-browser level. Click the "open in browser" button, or just find where the outputted file is and open it normally. That should render perfectly. Obviously it takes a few seconds because it is kicking the app into action on shinyapps.io, but as long as you are connected to the internet, it should work fine. (see my screenshot from the browser)

1 Like

Thank you for your answer!

Ah, I did not know this about the ticks and managed now to adapt my initial post accordingly. :smiley:

Thank you for the tip with the RStudio Browser! I see that it works for you in the screenshot! That's great, I unfortunately still cannot get it to run. It was not about the waiting, also after minutes I get no styles displayed & no functionality in the iframes. Tried with several browsers, and also on RStudio Server as well as on my local machine. I think also that the fact that I do get displayed something (the title of the app and the "Number of bins" + textbox without styles/functionality) does show that the app on shinyapps.io has powered up.

When I inspect the iframes in the rendered HTML output, it shows that they're not actually my desired URL, but they are actually serialized data (screenshot below), maybe some kind of snapshot of the URL was taken. It's possible for me to manually edit the knitted HTML and replace the iframe with the serialized data with my actual HTML code, then it works. Still I cannot figure out why the iframe HTML would not be taken as-is into the output HTML and why it does work for you.

In any case, thank you very much!

It is possible that you are using a recent version of Pandoc (that comes with a recent version of RStudio) that will encode this URL. We have a fix for that in the dev version of knitr for include_app()

It should be released on CRAN next week, but you could try update to the dev version.

This has to do with Pandoc now encoding iframe, and an attribute that needs to be set to tell Pandoc not to do it. For manual embedding you would need to add the attribute yourself. See Pandoc MANUAL
https://pandoc.org/MANUAL.html#option--self-contained

Hope it helps

I am not sure this is that or not.

1 Like

Hi cderv, thank you for your answer!
This seems to be the problem. I did not yet update to the dev-version of pandoc, but I've seen that the iframe embedding already works correctly when I state self_contained: false in the YAML header (with my current pandoc version 2.11.4) like this:

---
output: 
  html_document:
    self_contained: false
---

For my task at hand I unfortunately can have only 1 HTML file as output from the .Rmd and cannot have the CSS and JS script libraries in separated files. When embedding a "live"-iframe is only possible when the whole document is not self-contained, I think I cannot achieve this. Do I see this correctly, or can I for example say somehow that the whole document should be self-contained, but not the iframe?
In any case, thank you for your help!

See here for the Pandoc documentation about this:
https://pandoc.org/MANUAL.html#option--self-contained
I already posted the link above. It is explained what happens and what to do:

  • When using self contained document, all link will be encoded. including iframe
  • If you don't want this, you need to add the data-external=1 attributes.
  • New knitr version on CRAN will do that for you in include_url()

Hope it helps

1 Like

Great, thank you - it worked. For people that want this to get to work in RMarkdown, it's possible to add out.extra="data-external=1" to your chunk options, like you wrote here.

As I said above, this shouldn't be needed anymore with last knitr version released on CRAN this week. We have now included this into the include_url() function and the trick is not needed anymore with knitr 1.34

Glad it works!

1 Like