Website Screenshot API
for Ruby
Taking website screenshots in Ruby? You have three solid options: Ferrum (modern headless Chrome), Selenium (classic), or an API like GrabShot that handles the browser for you. Here's working code for each.
1. GrabShot API (No Browser Needed)
Ruby's standard library handles HTTP just fine. No gems needed.
require "net/http"
require "uri"
def screenshot(url, output = "screenshot.webp")
api_key = "YOUR_API_KEY" # Free at grabshot.dev
params = URI.encode_www_form(
url: url,
format: "webp",
width: "1440",
apiKey: api_key
)
uri = URI("https://grabshot.dev/v1/screenshot?#{params}")
response = Net::HTTP.get_response(uri)
raise "API error #{response.code}: #{response.body}" unless response.is_a?(Net::HTTPSuccess)
File.binwrite(output, response.body)
puts "Saved #{response.body.bytesize} bytes to #{output}"
end
screenshot("https://github.com")
With HTTParty (popular in Rails apps):
require "httparty"
def screenshot(url, output = "screenshot.webp")
response = HTTParty.get(
"https://grabshot.dev/v1/screenshot",
query: {
url: url,
format: "webp",
width: "1440",
deviceFrame: "macbook-air",
apiKey: ENV["GRABSHOT_API_KEY"]
}
)
raise "Error: #{response.code}" unless response.success?
File.binwrite(output, response.body)
end
2. Ferrum (Headless Chrome)
Ferrum is the modern Ruby way to control Chrome. Clean API, good defaults.
gem install ferrum
require "ferrum"
browser = Ferrum::Browser.new(
headless: true,
window_size: [1440, 900],
timeout: 30
)
browser.goto("https://github.com")
browser.screenshot(path: "github.png")
browser.quit
puts "Screenshot saved"
Full-page screenshot:
browser.goto("https://tailwindcss.com")
browser.screenshot(path: "full.png", full: true)
Pros: Clean Ruby API, full browser control, active development.
Cons: Needs Chrome installed. Uses 300-500MB RAM. Can crash on high-traffic servers.
3. Selenium WebDriver
The classic choice. Battle-tested, works with any browser.
gem install selenium-webdriver
require "selenium-webdriver"
options = Selenium::WebDriver::Chrome::Options.new
options.add_argument("--headless=new")
options.add_argument("--no-sandbox")
options.add_argument("--window-size=1440,900")
driver = Selenium::WebDriver.for(:chrome, options: options)
begin
driver.get("https://github.com")
driver.save_screenshot("github.png")
puts "Screenshot saved"
ensure
driver.quit
end
Rails Integration
Using GrabShot in a Rails controller:
# app/controllers/screenshots_controller.rb
class ScreenshotsController < ApplicationController
def capture
url = params.require(:url)
response = HTTParty.get(
"https://grabshot.dev/v1/screenshot",
query: {
url: url,
format: "png",
width: "1440",
apiKey: Rails.application.credentials.grabshot_api_key
}
)
if response.success?
send_data response.body,
type: "image/png",
disposition: "inline",
filename: "screenshot.png"
else
render json: { error: "Screenshot failed" }, status: :bad_gateway
end
end
end
# config/routes.rb
get "/screenshot", to: "screenshots#capture"
As a background job (Sidekiq/ActiveJob):
# app/jobs/screenshot_job.rb
class ScreenshotJob < ApplicationJob
queue_as :default
def perform(url, user_id)
response = HTTParty.get(
"https://grabshot.dev/v1/screenshot",
query: { url: url, format: "webp", apiKey: ENV["GRABSHOT_API_KEY"] }
)
if response.success?
user = User.find(user_id)
user.screenshots.attach(
io: StringIO.new(response.body),
filename: "#{URI.parse(url).host}.webp",
content_type: "image/webp"
)
end
end
end
# Usage:
ScreenshotJob.perform_later("https://example.com", current_user.id)
Comparison
| Feature | GrabShot API | Ferrum | Selenium |
|---|---|---|---|
| Chrome needed | No | Yes | Yes |
| Works on Heroku | Yes | With buildpack | With buildpack |
| RAM per screenshot | ~1MB | 300-500MB | 300-500MB |
| Device frames | Built-in | No | No |
| Page interaction | No | Full | Full |
See it in action
Try GrabShot right now — paste any URL and get a screenshot instantly. No signup needed.
Try Free Screenshot Tool →