How to Take Screenshots and Generate PDFs in Ruby on Rails
Rails developers have a few standard options for PDF generation: WickedPDF (wraps wkhtmltopdf), PDFKit (same), Prawn (draws PDFs programmatically), or Grover (wraps Puppeteer). Each adds a system dependency, a binary, or a Node.js runtime to your stack.
For screenshots there's no clean native option — most teams end up shelling out to Chrome.
Here's the alternative: one HTTP call, binary response, no system dependencies.
Screenshot from a URL
require 'net/http'
require 'json'
require 'uri'
def screenshot(url)
uri = URI('https://pagebolt.dev/api/v1/screenshot')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['x-api-key'] = ENV['PAGEBOLT_API_KEY']
request['Content-Type'] = 'application/json'
request.body = { url: url, fullPage: true, blockBanners: true }.to_json
response = http.request(request)
response.body
end
# Save to disk
File.binwrite('screenshot.png', screenshot('https://example.com'))
Or with the faraday gem:
def screenshot(url)
conn = Faraday.new('https://pagebolt.dev') do |f|
f.response :raise_error
end
response = conn.post('/api/v1/screenshot') do |req|
req.headers['x-api-key'] = ENV['PAGEBOLT_API_KEY']
req.headers['Content-Type'] = 'application/json'
req.body = { url: url, fullPage: true, blockBanners: true }.to_json
end
response.body
end
PDF from a URL
def pdf_from_url(url)
uri = URI('https://pagebolt.dev/api/v1/pdf')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['x-api-key'] = ENV['PAGEBOLT_API_KEY']
request['Content-Type'] = 'application/json'
request.body = { url: url, blockBanners: true }.to_json
http.request(request).body
end
PDF from an ERB template (replacing WickedPDF)
def pdf_from_template(template_name, locals = {})
# Render your existing ERB template to an HTML string
html = ApplicationController.renderer.render(
template: template_name,
layout: 'pdf',
locals: locals
)
uri = URI('https://pagebolt.dev/api/v1/pdf')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['x-api-key'] = ENV['PAGEBOLT_API_KEY']
request['Content-Type'] = 'application/json'
request.body = { html: html }.to_json
http.request(request).body
end
Use it in a controller action:
class InvoicesController < ApplicationController
def show
@invoice = Invoice.find(params[:id])
respond_to do |format|
format.html
format.pdf do
pdf = pdf_from_template('invoices/show', invoice: @invoice)
send_data pdf,
filename: "invoice-#{@invoice.id}.pdf",
type: 'application/pdf',
disposition: 'attachment'
end
end
end
end
No wkhtmltopdf binary, no Node.js sidecar, no Chromium layer. The existing ERB templates render as before — just swap the PDF generation step.
Narrated video recording
Same pattern, one more endpoint:
def record_video(steps, script)
uri = URI('https://pagebolt.dev/api/v1/video')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['x-api-key'] = ENV['PAGEBOLT_API_KEY']
request['Content-Type'] = 'application/json'
request.body = {
steps: steps,
audioGuide: { enabled: true, voice: 'nova', script: script },
pace: 'slow',
frame: { enabled: true, style: 'macos' }
}.to_json
http.request(request).body
end
Heroku / serverless deployment
No buildpacks, no apt-get, no binary layer. Add PAGEBOLT_API_KEY to your environment and deploy as normal. The capture runs on PageBolt's infrastructure.
Try it free — 100 requests/month, no credit card. → pagebolt.dev
Top comments (0)