Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copying output to clipboard in R Shiny

Tags:

r

shiny

I created a simple Shiny app in R that takes a URL and some UTM parameters and concatenates everything.

Now I would like to add a button to directly copy the output to clipboard.

I tried to adjust the rclipButton() function from the rclipboard package but my code copies something else instead of the produced character string.

library(shiny)
library(rclipboard)

shinyApp(
  ui = fluidPage(
    
    # URL input
    textInput("url", label = "Paste your URL", value = "https://google.com"),
    textInput("utm_source", label = "UTM source", value = "newsletter"),
    
    # URL + UTM output
    verbatimTextOutput("url_with_utm"),
    
    # Clipboard button
    uiOutput("clip"),
    
    textInput("clip_test", label = "Paste copied text")
  ),
  
  
  server = function(input, output) {
    
    # Define reactive value to store URL + UTM parameter
    url_with_utm <- reactiveValues(text = "")
    
    # Update URL + UTM parameters reactively
    observeEvent({
      input$url
      input$utm_source
    }, {
      url_with_utm$text <- paste0(input$url, "?", "utm_source=", input$utm_source)
    })
    
    # URL output for UI
    output$url_with_utm <- renderText({
      url_with_utm$text
    })
    
    # Clipboard button
    output$clip <- renderUI({
      rclipButton(
        inputId = "clipbtn",
        label = "Copy",
        clipText = url_with_utm$text, # IS THIS CORRECT??
        icon = icon("clipboard"),
        options = list(delay = list(show = 800, hide = 100), trigger = "hover")
      )
    })
    
  }
)
like image 501
ATellB Avatar asked Oct 26 '25 19:10

ATellB


1 Answers

You can write text to clipboard without the rclipboard() library using the JavaScript navigator.clipboard API and the Shiny to JavaScript API.

Define a JS function to write text to the clipboard

In your ui add a Shiny custom message handler. In this case, a function which takes some text and copies it to the clipboard. This means your UI will look like:

ui = fluidPage(
        tags$script("
            Shiny.addCustomMessageHandler('txt', function (txt) {
                navigator.clipboard.writeText(txt);
            });
        "), # this is new
        actionButton("copy_link", "Copy to clipboard"),
        # URL input
        textInput("url", label = "Paste your URL", value = "https://google.com"),
        textInput("utm_source", label = "UTM source", value = "newsletter"),
        textInput("paste_here", label = "Check copy/paste worked here"), # added for testing

        # URL + UTM output
        verbatimTextOutput("url_with_utm")
    )

Pass the URL string created in R to the JS function

In your server logic, add session$sendCustomMessage("txt", text) to the observe event. Your entire server logic can be:

server = function(input, output, session) {
        observeEvent(input$copy_link, {
            text <- paste0(input$url, "?", "utm_source=", input$utm_source)
            session$sendCustomMessage("txt", text)
        })
    }

Note that we need to pass session to the server as the custom message handler uses this argument.

Output

enter image description here

Browser compatibility

Depending on your IDE this might not work in the preview pane, as the navigator.clipboard API may not be supported. It should work in any modern browser. navigator.clipboard.writeText() has been supported in Chrome, Firefox and Opera since 2018, and in Safari and Edge since 2020. See here for more browser compatibility details.

like image 189
SamR Avatar answered Oct 29 '25 09:10

SamR



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!