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")
)
})
}
)
You can write text to clipboard without the rclipboard() library using the JavaScript navigator.clipboard API and the Shiny to JavaScript API.
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")
)
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.

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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With