Skip to contents

Capture visual screenshots of Shiny applications for documentation, visual regression testing, or bug reports. Use this instead of manual browser screenshots to ensure reproducible, scriptable captures with consistent viewport sizes and timing.

Choose the appropriate method based on your needs:

  • webshot2 (default): Fastest, best for static UI screenshots

  • shinytest2: Waits for Shiny reactivity to settle, best for dynamic apps

  • chromote: Maximum control via Chrome DevTools Protocol, best for complex scenarios

Usage

screenshot_app(
  app,
  file = NULL,
  method = c("webshot2", "shinytest2", "chromote"),
  vwidth = 1000,
  vheight = 700,
  delay = 0.5,
  selector = NULL,
  wait_for_idle = TRUE,
  load_timeout = 10000,
  port = NULL,
  max_wait_attempts = 50,
  cleanup = TRUE,
  zoom = 1,
  cliprect = NULL,
  expand = NULL,
  ...
)

Arguments

app

shiny.appobj. A Shiny app object created via shiny::shinyApp(). Must be a complete app with both UI and server components. Cannot pass app directories or URLs directly - wrap in shinyApp() first.

file

Character. Output file path for the screenshot (PNG format). If NULL (default), creates a tempfile in the R session temp directory. Parent directory must exist if specifying a custom path. Extension .png added if missing.

method

Character. Screenshot backend to use: "webshot2" (default, fast), "shinytest2" (waits for idle), or "chromote" (low-level control). Each method has different parameter support - see parameter descriptions for compatibility.

vwidth

Integer. Viewport width in pixels. Default 1000. Use 1920 for desktop, 768 for tablet, 375 for mobile screenshots.

vheight

Integer. Viewport height in pixels. Default 700. Adjust based on app content to avoid clipping or excess whitespace.

delay

Numeric. Seconds to wait before taking screenshot. Default 0.5. Increase for apps with slow-loading data, animations, or external API calls.

selector

Character. CSS selector to screenshot specific element instead of full page. Default NULL (full page). Examples: "#plot", ".sidebar", "#main-content".

wait_for_idle

Logical. Whether to wait for Shiny reactivity to settle before screenshot. Default TRUE. shinytest2 method only - ignored by other methods.

load_timeout

Integer. Milliseconds to wait for app to load. Default 10000. shinytest2 method only. Increase for slow-starting apps.

port

Integer. Specific port number for the app. Default NULL (random port). chromote method only. Useful for debugging or firewall configurations.

max_wait_attempts

Integer. Maximum connection retry attempts. Default 50. chromote method only. Each attempt waits 0.1s, so default = 5 second timeout.

cleanup

Logical. Whether to remove temporary app directory after screenshot. Default TRUE. Set FALSE to inspect the temporary files for debugging.

zoom

Numeric. Zoom factor for screenshot. Default 1. webshot2 method only. Use 2 for retina/high-DPI output.

cliprect

Numeric vector. Clipping rectangle as c(top, left, width, height). Default NULL (no clipping). webshot2 method only.

expand

Numeric vector. Pixels to expand screenshot beyond selector bounds. Default NULL. webshot2 method only. Useful to capture drop shadows or tooltips.

...

Additional arguments passed to the underlying screenshot function (webshot2::appshot(), shinytest2::AppDriver, or chromote::ChromoteSession).

Value

Character (invisible). Absolute path to the created screenshot file. Verify file exists before using in downstream operations.

See also

Other pkg-dev: setup_favicon()

Examples

if (FALSE) { # \dontrun{
library(shiny)

# Create a test app
app <- shinyApp(
  ui = fluidPage(h1("Test"), plotOutput("plot")),
  server = function(input, output) {
    output$plot <- renderPlot(plot(1:10))
  }
)

# Basic screenshot (webshot2, fastest)
screenshot_app(app, file = "app.png")

# Wait for reactivity to settle (shinytest2)
screenshot_app(app, method = "shinytest2", wait_for_idle = TRUE)

# Screenshot specific element
screenshot_app(app, selector = "#plot", file = "plot-only.png")

# Mobile viewport
screenshot_app(app, vwidth = 375, vheight = 667, file = "mobile.png")
} # }