Rails HTML to PDF
HTML to PDF Rails and How to Convert a Ruby on Rails View to a Real PDF
Turn a Rails view into a searchable, pixel accurate PDF with one call. Managed Chromium renders your real ERB or ViewComponent output with full CSS, web fonts and JavaScript, so you can leave the archived wkhtmltopdf binary behind without putting Chromium in your container. Try it on any URL or HTML below.
- PDF and archive in one call
- Plans from $49 a month
- Your HTML stays yours
Live demo
Runs in your browser. Nothing is uploaded. One PDF free to try, then a plan.
Your HTML
Live preview
Your PDF is downloading. That was the free one. The Starter plan converts as many as you need, for $49 a month or $288 a year, half price.
See the planShort answer
To convert HTML to PDF in Rails, render your view to a string with render_to_string, then hand that HTML to a renderer. The old default, WickedPDF, wraps wkhtmltopdf, which was archived in 2023 and receives no security patches, so it is not a safe choice for new apps. The current in-app options are Grover, which drives Chromium through Puppeteer and needs Node on the host, and Ferrum, which drives Chromium directly with no Node. Both mean shipping and scaling a browser yourself. The alternative is to POST the HTML to a rendering API. SitePDF renders it in managed Chromium and returns a true, selectable vector PDF, plus an optional timestamped archive of exactly what it rendered.
Written and fact checked by the SitePDF team.
Four ways to make a PDF in Rails, compared
Rails has no built-in PDF export, and the long-standing default is now on borrowed time. These four routes differ on rendering engine, what you must install and run, and whether your CSS and JavaScript survive.
| Approach | Engine | CSS and JavaScript | What you run | Best for |
|---|---|---|---|---|
| WickedPDF legacy |
wkhtmltopdf, an old WebKit fork | Dated CSS support, no modern layout; JavaScript is unreliable | A vendored wkhtmltopdf binary per platform | Existing apps only, as a temporary state with a migration planned |
| Grover Chromium via Node |
Chromium, driven through Puppeteer | Full modern CSS and JavaScript, it is a real browser | Node plus Puppeteer plus Chromium in your image | New apps where Node on the host is already acceptable |
| Ferrum PDF Chromium, no Node |
Chromium, driven directly over CDP from Ruby | Full modern CSS and JavaScript | Chromium in your image, but no Node runtime | Teams who want browser fidelity without adding Node |
| Managed Chromium API SitePDF |
Chromium, run and scaled by us | Full modern CSS and JavaScript | One HTTP call, no browser in your container | Production documents, exact fidelity, zero browser ops, a dated record |
The honest read: Grover and Ferrum are good gems and give you the same Chromium output we do, for free, if you are happy to install and scale a browser. Ferrum is the lighter of the two since it drops the Node layer. An API earns its place when a browser does not belong in your container at all, when your PDF traffic is spiky and you do not want to size a browser pool for peaks, or when you need a retrievable, timestamped record of what you rendered.
First, the WickedPDF situation
For a decade, "HTML to PDF in Rails" meant WickedPDF, and the pattern it popularized was genuinely good: you render a normal Rails view, in a normal layout, and get a PDF of it. The problem is not the gem, it is the engine underneath. WickedPDF shells out to wkhtmltopdf, and the wkhtmltopdf project was archived in 2023. It still runs, and plenty of production apps still use it, but nothing is being fixed, including security issues, and its rendering engine is an old WebKit fork that never learned modern CSS.
What that means in practice: a template written today with flexbox or CSS grid will not lay out correctly, web fonts are fragile, and JavaScript-driven content is a coin flip. If you have a WickedPDF app that works, there is no emergency, but treat it as a temporary state and pin your binary version. For anything new, start on a current engine. The wkhtmltopdf alternative page maps the replacements across every language, not just Ruby.
Grover and Ferrum run real Chromium in your infrastructure
The two in-app successors both give you Chromium, and the difference between them is the stack you have to carry. Grover drives Chromium through Puppeteer, which means Node and a Chromium download live in your image alongside Ruby. It keeps the familiar shape, so a WickedPDF migration is mostly mechanical: you still build HTML with render_to_string and pass it in. Ferrum talks to Chromium directly over the Chrome DevTools Protocol from Ruby, so the Node layer disappears and there is one less wrapper between your call and the browser.
Both are solid, and if you are comfortable running a browser they are the cheapest way to get browser-quality output. Be clear-eyed about what running a browser means, though. Chromium is memory hungry, a crashed or leaked browser process will take a Puma worker with it, and sizing a pool for a Monday-morning batch of statements is a real capacity exercise rather than a one-line config. Teams usually discover this the first time a month-end job renders two thousand documents at once.
The API path keeps the same Chromium with none of the ops
If you want browser fidelity but not a browser, the pattern stays the same and only the last step changes. Render your view to a string exactly as you would for Grover, then post it, or point the API at a live route in your app and let it load the page and run the JavaScript.
class InvoicesController < ApplicationController
def show
html = render_to_string(template: "invoices/show", layout: "pdf", formats: [:html])
response = Faraday.post("https://api.sitepdf.com/v1/render") do |req|
req.headers["Authorization"] = "Bearer #{ENV['SITEPDF_KEY']}"
req.body = { html: html, format: "Letter", archive: "true" }
end
redirect_to JSON.parse(response.body)["pdf_url"], allow_other_host: true
end
endYour asset pipeline output, Tailwind classes, web fonts and any JavaScript charts render the way they do in Chrome, and the PDF text stays selectable and searchable rather than becoming a flat image. Nothing runs a browser inside your dyno or pod, so a spike in PDF volume does not become a memory incident in your web tier. The same call works from a Sidekiq job for background generation, which is where most Rails PDF work belongs anyway. The PDF generator API page lists every parameter.
When the document is not really HTML, use Prawn
One honest caveat before you reach for any HTML renderer. If the document has no HTML version and never will, a shipping label, a boarding pass, a generated certificate, then Prawn is probably the right tool. It is pure Ruby, draws the page in code, has no browser or binary behind it, and is the fastest option because it skips a layout engine entirely. The trade is that you describe the document in Ruby rather than reusing a view, so it drifts from your web pages over time. Use Prawn when there is no page to mirror, and an HTML renderer when there is one.
Keep a dated copy of every document you generated
A generated invoice, quote or statement leaves your Rails app and nothing verifiable stays behind. Add archive=true to the render call and SitePDF also stores a timestamped, immutable snapshot of exactly what it rendered, retrievable by id later, so you can prove what a document said on a given date. The website archiving page explains how the record works, and if you are weighing running headless Chrome yourself, the Puppeteer alternative page runs that trade off honestly. Renders are transient by default; leave archiving off and we return the PDF and store nothing.
Which Rails PDF gem to pick for each situation
The choice comes down to one question, which is whether you want a browser in your own infrastructure. Everything else follows from the answer.
| Situation | Best fit |
|---|---|
| New feature, output must match Chrome, Node is welcome on the host | Grover |
| Same output, but you want to keep Node out of the image | Ferrum PDF |
| No HTML at all, a fixed structured document, speed matters | Prawn |
| Browser fidelity with no browser in your image, plus a dated archive of each document | Hosted rendering API |
| Legacy app on WickedPDF or PDFKit that already works | Leave it running and plan the migration |
The one answer that is off the table for new code is WickedPDF, and with it PDFKit, because both end at the archived wkhtmltopdf binary. If a Grover PDF comes out washed out next to the screen, set print_background: true. Chromium strips background colors and images in print mode unless told otherwise, and it is the most common Grover support question there is. If your answer to the browser question is a firm no, the Puppeteer alternative page covers converting HTML to PDF without headless Chrome and what each route costs in CSS fidelity.
curl https://api.sitepdf.com/v1/render \
-H "Authorization: Bearer $SITEPDF_KEY" \
-F url=https://app.example.com/invoices/8842 \
-F format=Letter \
-F print_background=true \
-F archive=true
{
"pdf_url": "https://api.sitepdf.com/v1/documents/doc_rb27f.pdf",
"pages": 2,
"rendered_in_ms": 1523,
"archive": {
"id": "arc_rb64d",
"captured_at": "2026-07-19T21:44:52Z",
"retrieve_url": "https://api.sitepdf.com/v1/archives/arc_rb64d"
}
}
This is the documented API call shape. Full request and response walkthrough.
Questions about this job
How do I convert HTML to PDF in Ruby on Rails?
Is WickedPDF still safe to use in 2026?
Grover or Ferrum, which should I use in Rails?
How do I generate a PDF in Rails without installing Chromium?
Should I use Prawn or an HTML to PDF renderer in Rails?
Index
More PDF and archiving tools
- Convert HTML to PDF
- Webpage to PDF
- URL to PDF API
- Website archiving
- Monitor website changes
- Screenshot API
- React to PDF
- Java PDF library
- C# PDF library
- Python PDF generation
- HTML to PDF Node.js
- Laravel HTML to PDF
- Vue to PDF
- Next.js PDF generator
- Angular to PDF
- Markdown to PDF API
- Django HTML to PDF
- Blazor HTML to PDF
- Spring Boot HTML to PDF
- Airtable to PDF
- PDF generator API
- Website archiving software
- Document generation API
- Legal document automation software
- Document automation software
- Bulk HTML to PDF
- Accessible PDF generation
- ADA compliance audit cost
- 508 compliance testing
- PDF remediation
- VPAT and ACR
- PDF accessibility checker
- Wayback Machine alternative
- Best HTML to PDF API
- DocRaptor alternative
- Puppeteer alternative
- Wkhtmltopdf alternative
- PDFShift pricing and alternative
- Urlbox pricing and alternative
- PDFCrowd alternative
- Api2Pdf alternative
- Browserless alternative
- APITemplate alternative
- CraftMyPDF alternative
- PDFMonkey alternative
- dompdf alternative
- Gotenberg alternative
- GrabzIt alternative
- Adobe PDF Services API
- PDF SDK pricing
- HTML to image API pricing
- Adobe Document Generation API pricing
- jsreport pricing
- PDFBolt pricing
- PDFEndpoint pricing
- Formstack Documents pricing
- Documint pricing
- iLovePDF API pricing
- Browserless pricing
- PandaDoc API pricing
- CloudConvert API pricing
- Encodian pricing
- IronPDF pricing
- Salesforce document generation pricing
- SelectPdf, HiQPdf and EvoPdf pricing
- CloudConvert alternative
- Direct mail API pricing
- E-signature API pricing
- Sparticuz Chromium Lambda cost
- Browserbase pricing
- Aspose PDF pricing
- PDF API pricing
- How it works
- Features
- Pricing
Get started
Render and archive with one API call
A pixel perfect PDF and a dated copy of the page from the same request. Plans from $49 a month, half price billed yearly.