Let user download preexisting file in Shiny

Hi!

Here is what the folder for my app looks like:


app.R
server.R
ui.R
www/ (this is a folder)

Inside the www/ folder is a txt file, testfile.txt.

In ui.R, I have the following code:

downloadButton("unit01file01", label = "Example Programs")

In server.R:

server <- function(input, output, session) {
  # Download unit 1 files
  output$unit01file01 <- downloadHandler( # Example programs
    filename = "mytestfile.txt",
    content = function(file) {
      file.copy(file.path(getwd(),'www','testfile.txt'), file)
    },
    contentType = "text/plain"
  )
}

However, the download is giving me an html file (presumably of the app), instead of the desired file we want to download, testfile.txt. What am I doing wrong here?

Thanks!

Your code works for me, both running it on my PC (from RStudio) and running it from shinyapps.io. Does the error occur when running it locally (from RStudio or from a terminal), or when running it from a server? If running from a server, did you install the www folder and the text file on the server?

I'm running it from RStudio. Here's the full code:

app.R:

################################################################################
rm(list = ls())
library(shiny)
library(shinyFiles)
library(bslib)
library(thematic)
library(shinydashboard)

source("ui.R")
source("server.R")

set.seed(500)

shinyApp(ui = ui, server = server) # Run app



ui.R:

rm(list = ls())
library(shiny)
library(shinyFiles)
library(bslib)
library(thematic)
library(shinydashboard)
set.seed(500)

ui <- dashboardPage(
  skin = "black",
  dashboardHeader(
    title = "The Basics of TI-BASIC",
    titleWidth = 250
  ),
  dashboardSidebar(
    width = 250,
    sidebarMenu(
      menuItem("Unit 01: Introduction", tabName = "unit00"),
      menuItem("Unit 01: Input and Output", tabName = "unit01")
    )
  ),
  dashboardBody(
    tabItems(
      tabItem(
        tabName = "unit00",
        fluidRow(
          # Embed video
          box(
            title = "Watch the Lesson",
            tags$iframe(src=(youtube link), 
                        frameborder="0", 
                        allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture")
          ),
          # Files for student
          box(
            title = "No files to download!"
          )
        )
      ),
      tabItem(
        tabName = "unit01",
        fluidRow(
          # Embed video
          box(
            title = "Watch the Lesson",
            tags$iframe(src=(there's a youtube link here that works fine), 
                        frameborder="0", 
                        allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture")
          ),
          # Files for student
          box(
            title = "Download Files",
            downloadButton("unit01file01", label = "Example Programs")
          )
        )
      )
    )
  )
)

server.R:

rm(list = ls())
library(shiny)
library(shinyFiles)
library(bslib)
library(thematic)
library(shinydashboard)
set.seed(500)

server <- function(input, output, session) {
  # Download unit 1 files
  output$unit01file01 <- downloadHandler( # Example programs
    filename = "mytestfile.txt",
    content = function(file) {
      file.copy(file.path(getwd(),'www','testfile.txt'), file)
    },
    contentType = "text/plain"
  )
}

Your UI file contains some issues that convince RStudio that the file ends prematurely. In the two tag$iframe commands, I had to surround the src argument with quotes. That should have nothing to do with file download.

I put a folder named "www" in the folder containing the three .R files, and put a text file named testfile.txt in the www folder. With that, the download feature worked fine for me.

1 Like

This topic was automatically closed 54 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.