Skip to content

Instantly share code, notes, and snippets.

@forsbergplustwo
Last active May 15, 2023 18:46
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save forsbergplustwo/da777dd47f343408ad9adc29e21ad674 to your computer and use it in GitHub Desktop.
Save forsbergplustwo/da777dd47f343408ad9adc29e21ad674 to your computer and use it in GitHub Desktop.
Generating PDFs in Ruby, using Ferrum gem on Heroku

Generating PDFs in Ruby, using Ferrum gem on Heroku

by Bjorn Forsberg

image

Ferrum is a pure Ruby gem, providing a high-level API to control Chrome, which runs headless by default. Ferrum is a great alternative to Node's Puppeteer library, which is a pain to use with Ruby and Heroku.

Ferrum can be used for any browser scripting work, as well as for generating screenshots and PDFs. We use it mainly for PDF generation, hosted on Heroku, and the setup flow goes like this:

  1. Add Chromium locally if not already done: brew install chromium
  2. Add gem "ferrum" to Gemfile
  3. Add the needed code to your app, which handles generating the PDF file (simplified example):
          url = "https://example.com/"
          filename = "My file name".parameterize
          tmp = Tempfile.new("pdf-chrome-#{filename}")
          browser = Ferrum::Browser.new
          browser.go_to(url)
          sleep(0.3) # Simple way to handle slow JS
          browser.pdf(
            path: tmp.path,
            format: :A4,
            landscape: false,
            margin: {top: 36, right: 36, bottom: 36, left: 36},
            preferCSSPageSize: true,
            printBackground: true
          )
          browser.quit
          pdf_data = File.read(tmp.path)
          pdf_filename = filename + ".pdf"
          send_data(pdf_data, filename: pdf_filename, type: "application/pdf", disposition: "inline")
  1. Test and commit
  2. Add the chrome buildpack to Heroku, as the first buildpack in the list: heroku buildpacks:add heroku/google-chrome --index 1

You should then see:

Buildpack added. Next release on your-app-name will use:
  1. heroku/google-chrome
  2. heroku/ruby
  1. Add the following config variable, to tell Heroku/Ferrumwhere it can find the installed Chrome browser: heroku config:set BROWSER_PATH="/app/.apt/usr/bin/google-chrome"
  2. Commit and push the changes to git + heroku, all done!

Sidenote: When migrating from Puppeteer to Ferrum, my Heroku slug size also got roughly 200Mb smaller, and deploys are much quicker due to needing fewer buildpacks 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment