The official Ruby SDK for RenderScreenshot - a developer-friendly screenshot API for capturing web pages programmatically.
Add this line to your application's Gemfile:
gem 'renderscreenshot'And then execute:
bundle installOr install it yourself as:
gem install renderscreenshot- Ruby 3.0 or higher
require 'renderscreenshot'
# Create a client
client = RenderScreenshot.client('rs_live_your_api_key')
# Take a screenshot
image_data = client.take(
RenderScreenshot::TakeOptions
.url('https://example.com')
.width(1200)
.height(630)
.format('png')
)
# Save to file
File.binwrite('screenshot.png', image_data)RenderScreenshot.configure do |config|
config.base_url = 'https://api.renderscreenshot.com' # Default
config.timeout = 30 # Default timeout in seconds
endclient = RenderScreenshot.client(
'rs_live_your_api_key',
base_url: 'https://custom.api.com',
timeout: 60
)# Get screenshot as binary data
image_data = client.take(
RenderScreenshot::TakeOptions
.url('https://example.com')
.preset('og_card')
)# Get screenshot URL and metadata
response = client.take_json(
RenderScreenshot::TakeOptions
.url('https://example.com')
.preset('og_card')
)
puts response['image']['url'] # CDN URL
puts response['image']['width'] # 1200
puts response['image']['height'] # 630
puts response['cache']['key'] # Cache key for later referenceThe TakeOptions class provides a fluent interface for configuring screenshots:
options = RenderScreenshot::TakeOptions
.url('https://example.com')
# Viewport
.width(1920)
.height(1080)
.scale(2)
.mobile(true)
# Capture
.full_page
.element('#main-content')
.format('webp')
.quality(90)
# Wait conditions
.wait_for('networkidle')
.delay(500)
.wait_for_selector('.loaded')
# Blocking
.block_ads
.block_trackers
.block_cookie_banners
# Browser emulation
.dark_mode
.timezone('America/New_York')
.locale('en-US')# Social card presets
options = RenderScreenshot::TakeOptions
.url('https://example.com')
.preset('og_card') # 1200x630 for Open Graph
# Device presets
options = RenderScreenshot::TakeOptions
.url('https://example.com')
.device('iphone_14_pro')options = RenderScreenshot::TakeOptions
.url('https://example.com')
.format('pdf')
.pdf_paper_size('a4')
.pdf_landscape
.pdf_print_background
.pdf_margin('1cm')
pdf_data = client.take(options)
File.binwrite('document.pdf', pdf_data)# Simple batch (same options for all URLs)
response = client.batch(
['https://example1.com', 'https://example2.com', 'https://example3.com'],
options: RenderScreenshot::TakeOptions.url('').preset('og_card')
)
response['results'].each do |result|
puts "#{result['url']}: #{result['status']}"
end
# Advanced batch (per-URL options)
response = client.batch_advanced([
{ url: 'https://example1.com', options: { preset: 'og_card' } },
{ url: 'https://example2.com', options: { preset: 'twitter_card' } }
])Generate signed URLs for client-side use without exposing your API key:
options = RenderScreenshot::TakeOptions
.url('https://example.com')
.preset('og_card')
# URL expires in 24 hours
signed_url = client.generate_url(options, expires_at: Time.now + 86400)
# Use in HTML
# <img src="#{signed_url}" />cache = client.cache
# Get cached screenshot
data = cache.get('cache_key_123')
# Delete cached entry
cache.delete('cache_key_123')
# Bulk purge
cache.purge(['key1', 'key2', 'key3'])
# Purge by URL pattern
cache.purge_url('https://example.com/*')
# Purge by date
cache.purge_before(Time.now - 86400 * 7) # Older than 7 days
# Purge by storage path pattern
cache.purge_pattern('screenshots/2024/01/*')# List all presets
presets = client.presets
presets.each { |p| puts "#{p['id']}: #{p['name']}" }
# Get specific preset
preset = client.preset('og_card')
# List all devices
devices = client.devices
devices.each { |d| puts "#{d['id']}: #{d['name']} (#{d['width']}x#{d['height']})" }# In your webhook endpoint
def webhook_handler(request)
payload = request.body.read
signature, timestamp = RenderScreenshot::Webhook.extract_headers(request.headers)
unless RenderScreenshot::Webhook.verify(
payload: payload,
signature: signature,
timestamp: timestamp,
secret: ENV['WEBHOOK_SECRET']
)
return [401, 'Invalid signature']
end
event = RenderScreenshot::Webhook.parse(payload)
case event[:event]
when 'screenshot.completed'
handle_screenshot_completed(event[:data])
when 'screenshot.failed'
handle_screenshot_failed(event[:data])
when 'batch.completed'
handle_batch_completed(event[:data])
end
[200, 'OK']
endAll API errors inherit from RenderScreenshot::Error:
begin
client.take(RenderScreenshot::TakeOptions.url('https://example.com'))
rescue RenderScreenshot::ValidationError => e
puts "Invalid request: #{e.message}"
rescue RenderScreenshot::AuthenticationError => e
puts "Auth failed: #{e.message}"
rescue RenderScreenshot::RateLimitError => e
puts "Rate limited. Retry after #{e.retry_after} seconds"
sleep(e.retry_after) if e.retry_after
retry
rescue RenderScreenshot::TimeoutError => e
puts "Request timed out" if e.retryable?
rescue RenderScreenshot::ServerError => e
puts "Server error: #{e.message}"
retry if e.retryable?
rescue RenderScreenshot::ConnectionError => e
puts "Connection failed: #{e.message}"
endError properties:
http_status- HTTP status codecode- Error code from APImessage- Human-readable messagerequest_id- Request ID for supportretry_after- Seconds to wait (rate limits)retryable?- Whether the error can be retried
| Category | Methods |
|---|---|
| Viewport | width, height, scale, mobile |
| Capture | full_page, element, format, quality |
| Wait | wait_for, delay, wait_for_selector, wait_for_timeout |
| Preset | preset, device |
| Blocking | block_ads, block_trackers, block_cookie_banners, block_chat_widgets, block_urls, block_resources |
| Page | inject_script, inject_style, click, hide, remove |
| Browser | dark_mode, reduced_motion, media_type, user_agent, timezone, locale, geolocation |
| Network | headers, cookies, auth_basic, auth_bearer, bypass_csp |
| Cache | cache_ttl, cache_refresh |
pdf_paper_size, pdf_width, pdf_height, pdf_landscape, pdf_margin, pdf_margin_top, pdf_margin_right, pdf_margin_bottom, pdf_margin_left, pdf_scale, pdf_print_background, pdf_page_ranges, pdf_header, pdf_footer, pdf_fit_one_page, pdf_prefer_css_page_size |
|
| Storage | storage_enabled, storage_path, storage_acl |
After checking out the repo:
bundle install
bundle exec rake test # Run tests
bundle exec rubocop # Run linter
bundle exec rake # Run bothThis project uses pre-commit hooks to prevent secrets from being committed:
# Install pre-commit (if not already installed)
brew install pre-commit # macOS
pip install pre-commit # or via pip
# Install the hooks
pre-commit install
# Run manually on all files
pre-commit run --all-filesThe hooks include:
- Gitleaks - Scans for secrets and API keys
- detect-private-key - Prevents committing private keys
- check-added-large-files - Prevents large files (>500KB)
Bug reports and pull requests are welcome on GitHub at https://github.com/renderscreenshot/renderscreenshot-ruby.
The gem is available as open source under the terms of the MIT License.