Trouble including image (jpeg, png, svg, etc.) in shiny app embedded in R package

I'm having trouble including images in a shiny app that is embedded in an R package (just getting a broken link). I've created a minimal reproducible R package on GitHub (https://github.com/mdlama/imageissue) where I've essentially embedded the Hello Shiny! example into a function hello.shiny() and added a jpeg image. Here's the function from the package (link on GitHub):

#' Hello Shiny!
#'
#' @import shiny
#'
#' @export
hello.shiny <- function() {
  ui <- fluidPage(

    # Application title
    titlePanel("Hello Shiny!"),

    # Sidebar with a slider input for number of observations
    sidebarLayout(
      sidebarPanel(
        sliderInput("obs",
                    "Number of observations:",
                    min = 1,
                    max = 1000,
                    value = 500)
      ),

      # Show a plot of the generated distribution
      mainPanel(
        plotOutput("distPlot"),
        div(
          img(src = system.file("www/img/helloworld.jpg", package="imageissue"))
        )
      )
    )
  )

  server <- function(input, output) {

    # Expression that generates a plot of the distribution. The expression
    # is wrapped in a call to renderPlot to indicate that:
    #
    #  1) It is "reactive" and therefore should be automatically
    #     re-executed when inputs change
    #  2) Its output type is a plot
    #
    output$distPlot <- renderPlot({

      # generate an rnorm distribution and plot it
      dist <- stats::rnorm(input$obs)
      graphics::hist(dist)
    })

  }

  hello.shiny.app <- shinyApp(ui = ui, server = server)
  runApp(hello.shiny.app, launch.browser = TRUE)
}

I've attempted to embed an image after the plotOutput using the following code:

div(
  img(src = system.file("www/img/helloworld.jpg", package="imageissue"))
)

This was recommended by Joe Cheng on a Google Group discussion here. In that same discussion, Dean Attali recommends putting the Shiny app in the inst directory of the package, but I'd rather not do that as the package I am developing is basically the Shiny app itself and would like to work from the R directory where all the package code goes if possible.

I think I've done my due diligence and searched the back-alleys and armpits of the internet for solutions but couldn't find any. Any ideas? Thanks for your help!

The addResourcePath function can help with this. I think using a www file to store static assets causes path conflicts. I would recommend moving the files into a new folder in inst. I created a new folder called assets and moved the image into there.

+ inst / 
     - assets /
           helloworld.jpg

Create a zzz.R file in the R/ directory and define the path using onLoad or onAttach (depending on your setup; see chapter 6 of R Packages for more information). It is also recommended to use onUnload.

# zzz.R
.onLoad <- function(libname, pkgname) {
  shiny::addResourcePath(
    prefix = "assets",
    directoryPath = system.file(
      "assets",
      package = "imageissue"
    )
  )
}

.onUnload <- function(lib name, pkgname) {
   shiny::removeResourcePath("assets")
}

In the UI, you can call the image using resource path + filename.

img(src = "assets/helloworld.jpg")  # prefix + filename

Rebuild and reinstall the package. The image should be appear when you run the app.

1 Like

Awesome, fixed! I was actually able to keep the image in the www/img directory by changing your zzz.R as follows:

# zzz.R
.onLoad <- function(libname, pkgname) {
  shiny::addResourcePath(
    prefix = "img",
    directoryPath = system.file(
      "www/img",
      package = "imageissue"
    )
  )
}

.onUnload <- function(libname, pkgname) {
  shiny::removeResourcePath("img")
}

The link to the image in the UI is thus:

img(src = "img/helloworld.jpg")

The GitHub repo is updated with the fix. Thanks so much!!

1 Like

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