Seamless embedding of an HTML page in a Shiny app

I'm developping an app to analyse DNA sequences. The app calls an external tool in the background that generates outputs as HTML files. The HTML files are stored in a temporary directory before being read and displayed on the app. Currently, I use tags$iframe() to display the content of HTML files. The problem is that HTML files aren't seamlessly embedded in the app, they remain in the iframe which is limited in size. This tends to create multiple vertical scrolling bars (e.g. one for the iframe and another one for the overall page), which I find inconvenient.

Is there a way to embed the content of the HTML file as if it was actually part of the main page? I tried tags$iframe(seamless = NA) but doesn't seem to have any effect.

I presume I need to tweak the embedded HTML file first to remove the <html></html> tag. What's the recommend approach to do it?

Here's a reproducible example using an online HTML file for simplicity purpose:

library(shiny)

ui <- fluidPage(
  htmlOutput("html")
)

server <- function(input, output, session) {
    output$html <- renderUI({
      tags$iframe(
        srcdoc = readr::read_file("https://www.sheldonbrown.com/web_sample1.html"),
        width = "100%",
        style = "height: 100vh",
        frameBorder = "0"
      )
    })
}

shinyApp(ui, server)

How about this?

library(shiny)

ui <- fluidPage(
  htmlOutput("html")
)

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

  output$html <- renderUI({
    HTML(readr::read_file("https://www.sheldonbrown.com/web_sample1.html"))
  })
}

shinyApp(ui, server)

Thanks for this. For some reasons, that breaks all the buttons on the page. I initially tried with includeHTML() that did the same thing.

See the images below:

(before displaying the HTML file)

(after displaying the HTML file)

Oddly enough, I can't reproduce it with your example. I thought it was a bug with includeHTML()/HTML() but that might be something else.

Using a button to display the HTML file tends to create an empty space at the top of the page everytime the button is clicked though:

library(shiny)

ui <- fluidPage(
  actionButton("btn", "Click me!"),
  htmlOutput("html"),
)

server <- function(input, output, session) {
  observeEvent(input$btn, {
    output$html <- renderUI({
      HTML(readr::read_file("https://www.sheldonbrown.com/web_sample1.html"))
    })
  })
}

shinyApp(ui, server)

Hmm that does seem as if it's something in the embedded HTML affecting the rest of it. You can keep just the body of the embedded page like this, but that might break something inside it?

server <- function(input, output, session) {
  observeEvent(input$btn, {
    output$html <- renderUI({
      rvest::read_html("https://www.sheldonbrown.com/web_sample1.html") |>
        rvest::html_node("body") |>
        as.character() |>
        HTML()
    })
  })
}

The whitespace issue seems to be specific to this example url - it's some ancient googlead stuff which is leaking into the app.

1 Like

I think this is the same problem? html - How to Make iframe 100% height according to its content - Stack Overflow

1 Like

Ah yes you're right, it's the CSS within the HTML document that's affecting the rest of the app.

Will see how easy it's to fix the CSS and use the HTML() solution if I can, otherwise I'll try the stackoverflow solution. Thanks!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.