8

I'm trying to put a static image into a Shiny app. I have created a folder called www in the working directory of my Shiny app and put a PNG file there. Using the following code should show the image:

library(shiny)

ui <- fluidPage(
  tags$img(src='photo.png')
)
  
server <- function(input, output) {}

shinyApp(ui=ui, server=server)

But instead I have this:

enter image description here

Querying the image URL (http://127.0.0.1:7122/photo.png) directly shows a 404 status code.

The outcome is the same regardless of whether I start the Shiny app by running the code manually, clicking the "Run App" button in RStudio, or executing the file via Rscript app.R on the command line.

Here is the folder structure:

.
├── app.R
└── www
    └── photo.png

Am I missing something?

9
  • I tested your code and it worked fine. The only thing I can think of is maybe your photo isn't named photo? src='photo.png' means that your file is called "photo.png". If that is the case then sorry otherwise replace "photo" with your file name. That's the only problem I can think of assuming the www folder is in your app folder (as mentioned in the answer below). Commented Oct 30, 2018 at 15:11
  • @EliBerkow I've taken the liberty of adding some more details to this (old) question. The code definitely doesn't work for me; not on Windows, nor on Linux. This is true across different versions of R and Shiny. The app otherwise works, but static resources don't get served under /. By contrast, adding a new resource prefix via addResourcePath works. Commented Nov 29, 2022 at 14:38
  • That is very strange. I tried again and it works fine for me. I'm assuming running in the browser gives the same outcome? Commented Nov 29, 2022 at 14:54
  • 1
    @Dirk According to the documentation, it gets the prefix /. Commented Nov 29, 2022 at 15:35
  • 2
    I’ve reported a bug. Commented Nov 29, 2022 at 17:18

2 Answers 2

6
+250

I don't think this is a bug - there is some documentation missing.

The issue here is, that the default resource publishing via the www folder using the / prefix is implemented only for two-file (server.R and ui.R) and single-file (app.R) shiny apps - not for shiny app objects (the object returned by shinyApp()). This makes sense, as in contrast to e.g. the app.R file a shiny app object doesn't reside in a fixed directory.

The www folder to / prefix mapping only takes place if runApp's appDir parameter is provided with a directory or file path (string object). The character method can be seen here. Another relevant function (downstream) can be found here.

Once a shiny app object is passed to runApp's appDir argument we need to use addResourcePath, which is the case when running runApp(shinyApp(ui, server)).

Accordingly the following works:

library(shiny)

addResourcePath("prefix", "www")

ui <- fluidPage(
  tags$img(src='prefix/photo.png')
)

server <- function(input, output) {}

appObj <- shinyApp(ui=ui, server=server)

runApp(appObj)
# print(appObj) # also works
Sign up to request clarification or add additional context in comments.

7 Comments

If nothing else it's a bug in the documentation. Furthermore, you cannot use addResourcePath with the prefix /, so there seemingly is no way to make this work with an app object. What this answer is missing (for me) is a workaround/fix to make the original code work.
@KonradRudolph I definitely agree - the documentation regarding resource publishing via the www directory is poor. Without modifying shiny I don't think there is a way to make the original code work (as a shiny object) because as you already mentioned slashes are not allowed in the prefix using addResourcePath - for future readers please check ?addResourcePath.
@KonradRudolph the only thing you could do (if you want to avoid using addResourcePath) is copying your resources to shiny's fallbackWWWDir located here: system.file("www-dir", package = "shiny"). Please see this line.
That location will not generally be user-writeable, nor should it be modified (it's part of the package installation, after all!). Luckily in my particular case I can just use runApp('.') instead. But in general I think shinyApp needs to gain an argument to specify the www path. In the meantime, a generally usable workaround requires generating the necessary Shiny file/folder structure on the fly (i.e. create an app.r file adjacent to the www dir, write the Shiny app into it, and then run shinyApp('app.r').
Yes - a proper built-in solution should be the way to go - My answer is just reflecting the status quo. Let's see what the shiny team responds on GitHub.
|
3

It seems that this is a bug in Shiny.

Until this is fixed, there are two rough workaround strategies:

  1. Convince Shiny that www should be mapped in a shinyApp object. To do this, we need to modify the shinyApp object:

    library(shiny)
    
    ui <- fluidPage(
      tags$img(src = 'photo.png')
    )
    
    server <- function(input, output) {}
    
    app <- shinyApp(ui = ui, server = server)
    app$staticPaths <- list(
      `/` = httpuv::staticPath(
        file.path(getwd(), "www"), indexhtml = FALSE, fallthrough = TRUE
      )
    )
    
    app
    

    (Solution based on a RStudio Community discussion.)

  2. Launch Shiny without using the shinyApp object directly:

    • by pressing the “Run App” button in RStudio, or
    • by executing runApp('.') or runApp('app.R').

    Other ways of launching the app do not work! Notably, this also includes replacing the last line in the script with runApp(shinyApp(ui, server)).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.