FerrumPdf Documentation

repository·main·Indexed 19 days ago

https://github.com/excid3/ferrum_pdf

A Ruby wrapper around the Ferrum CDP-based browser automation library used to render HTML or URLs into PDFs and screenshots. It includes custom renderers for Rails controllers, global configuration options for PDF and screenshot output, and guides for deploying in Docker and on Fly.io.

Tokens
4K
Snippets
15
Records
15
Agent score
67%

What's inside FerrumPdf

  1. Manage the Ferrum browser instance

    main

    FerrumPdf manages a single Chrome browser instance per Ruby process. It is automatically created on the first use and is thread-safe within a single process.

    Custom Browser: You can provide your own Ferrum::Browser instance to use instead of the auto-created one.

    Shutdown: To shut down the current browser and allow the next call to create a new one, set FerrumPdf.browser = nil.

    Per-call Browser: You can also pass a specific browser instance to an individual render call.

    # Use a custom browser instance
    custom_browser = Ferrum::Browser.new(window_size: [800, 600], headless: false)
    FerrumPdf.browser = custom_browser
    FerrumPdf.render_pdf(url: "https://example.org")
    
    # Pass a browser to a single call
    other_browser = Ferrum::Browser.new
    FerrumPdf.render_pdf(url: "https://example.org", browser: other_browser)
    
    # Shutdown current browser
    FerrumPdf.browser = nil
  2. Render PDFs and Screenshots from Rails controllers

    main

    FerrumPdf provides custom renderers for Rails controllers to simplify PDF and screenshot generation within the request/response cycle.

    For PDFs: Use render ferrum_pdf: { ... }. For Screenshots: Use render ferrum_screenshot: { ... }.

    You can pass standard Rails rendering options like layout, template, disposition, and filename, alongside FerrumPdf-specific options.

    # In a Rails controller for PDF
    def show
      render ferrum_pdf: {
        display_header_footer: true,
        header_template: FerrumPdf::DEFAULT_HEADER_TEMPLATE
      },
      layout: "pdf",
      template: "pdf",
      disposition: :inline,
      filename: "example.pdf"
    end
    
    # In a Rails controller for Screenshot
    def show
      render ferrum_screenshot: {
        format: "png",
        full: true
      },
      disposition: :inline,
      filename: "example.png"
    end
  3. Debug FerrumPdf with non-headless mode and blocks

    main

    If you need to debug the rendering process, you can use two methods:

    1. Non-headless mode: Set config.headless = false in the configuration block to see the Chrome window.
    2. Execution blocks: Pass a block to render_pdf or render_screenshot. This block is executed after the page loads but before the render occurs. The block yields the Ferrum::Browser and Ferrum::Page objects.

    Inside the block, you can call browser.debug to open Chrome DevTools or use binding.irb to pause execution.

    # Debugging with a block
    FerrumPdf.render_pdf(url: "https://google.com") do |browser, page|
      # Open Chrome DevTools
      browser.debug
    
      # Or use standard Ruby debugging
      binding.irb
    end
  4. Install Google Chrome in Docker

    main

    To use FerrumPdf in a Docker environment, you must install Google Chrome in your image. Use the following snippet in your Dockerfile:

    RUN apt-get update && apt-get install gnupg wget -y && \
        wget --quiet --output-document=- https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor > /etc/apt/trusted.gpg.d/google-archive.gpg && \
        sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' && \
        apt-get update && \
        apt-get install google-chrome-stable -y && \
        rm -rf /var/lib/apt/lists/*

    Note: For security in Docker, using seccomp is recommended over the --no-sandbox flag.

  5. Configure Dockerfile dependencies for Fly.io

    main

    To use FerrumPdf on Fly.io, you must install Chromium and its required dependencies in your Dockerfile. You should also set the DOCKER_BUILD environment variable to 1 to prevent the FerrumPdf initializer from attempting to start the browser during the image build phase, which would cause a timeout.

    ENV DOCKER_BUILD=1
    RUN apt-get update -qq && \
        DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
        chromium chromium-sandbox fonts-liberation libappindicator3-1 xdg-utils && \
        rm -rf /var/lib/apt/lists/* /var/cache/apt
  6. Initialize FerrumPdf for Fly.io

    main

    Fly.io requires Chrome to run without the sandbox. In your Rails initializer, you must pass the 'no-sandbox' => nil option within browser_options. Additionally, you should explicitly set the browser_path to '/usr/bin/chromium' in production environments.

    To prevent timeouts during the Docker build process, skip initialization if the DOCKER_BUILD environment variable is present.

    # config/initializers/ferrum.rb
    
    return if ENV['DOCKER_BUILD']
    
    options = {
      process_timeout: 30,
      browser_options: {
        'no-sandbox' => nil
      }
    }
    
    options = options.merge(browser_path: '/usr/bin/chromium') if Rails.env.production?
    
    FerrumPdf.browser(options)
  7. Configure FerrumPdf defaults

    main

    Use the FerrumPdf.configure block to set global defaults for page loading, PDF rendering, screenshot rendering, and browser settings. This avoids repeating configuration in every call.

    FerrumPdf.configure do |config|
      # Page loading defaults
      config.page_options.authorize = { user: "username", password: "password" }
      config.page_options.viewport = { width: 1200, height: 800, scale_factor: 3 }
    
      # PDF defaults
      config.pdf_options.margin_top = 0.2
      config.pdf_options.margin_bottom = 0.2
    
      # Screenshot defaults
      config.screenshot_options.format = :png
      config.screenshot_options.full = false
    
      # Browser defaults
      config.window_size = [1920, 1080]
      config.headless = true
    end
  8. Render PDFs using FerrumPdf.render_pdf

    main

    You can generate PDFs from either a URL or raw HTML content using the FerrumPdf.render_pdf method.

    When providing HTML content via the html: key, it is recommended to also provide the display_url: key. This allows Chrome to correctly process relative paths within the document. If omitted, http://example.com is used as the default base URL.

    # From a URL
    FerrumPdf.render_pdf(url: "https://google.com")
    
    # From HTML content
    FerrumPdf.render_pdf(html: content, display_url: "https://example.com")
  9. Render Screenshots using FerrumPdf.render_screenshot

    main

    Generate screenshots from a URL or HTML content using FerrumPdf.render_screenshot. Use the screenshot_options hash to control the output.

    Key options include:

    • format: "png" or "jpeg".
    • quality: Integer 0-100 (for JPEG only).
    • full: Boolean; if true, captures the full page; if false, captures the viewport.
    • selector: CSS selector for a specific element to screenshot.
    • area: A hash {x: 0, y: 0, width: 100, height: 100} for a specific region.
    • scale: Float for zoom level.
    • background_color: A Ferrum::RGBA object.
    # From a URL
    FerrumPdf.render_screenshot(url: "https://google.com")
    
    # With specific options
    FerrumPdf.render_screenshot(
      url: "https://example.com",
      screenshot_options: {
        format: "png",
        full: true,
        selector: ".main-content"
      }
    )
  10. Configure FerrumPdf settings

    main

    Use FerrumPdf.configure to set global configuration options. The configuration object uses ActiveSupport::OrderedOptions and contains the following top-level keys:

    • window_size: An array [width, height] (e.g., [1920, 1080]).
    • page_options: Options passed to page loading (e.g., authorize, retries, viewport, wait_for_idle_options, timeout_if_open_connections).
    • pdf_options: Options passed to the PDF rendering engine.
    • screenshot_options: Options passed to the screenshot engine.
    FerrumPdf.configure do |config|
      config.window_size = [1280, 720]
      config.pdf_options.merge!(display_header_footer: true)
      config.page_options.merge!(retries: 3)
    end
  11. Configure PDF rendering options

    main

    The FerrumPdf.render_pdf method accepts a pdf_options hash to customize the output.

    Key options include:

    • landscape: Boolean for paper orientation.
    • scale: Scale of the webpage rendering.
    • format: Paper format.
    • paper_width / paper_height: Dimensions in inches.
    • page_ranges: Specific pages to print (e.g., "1-5, 8 11-13").
    • margin_top, margin_bottom, margin_left, margin_right: Margins in inches (defaults to 1cm).
    • display_header_footer: Boolean to enable headers/footers.
    • print_background: Boolean to print background graphics.
    • header_template / footer_template: HTML templates for headers and footers.

    Header/Footer Variables: You can use the following CSS classes in your templates to inject dynamic content:

    • date: Formatted print date
    • title: Document title
    • url: Document location
    • pageNumber: Current page number
    • totalPages: Total pages in the document
    FerrumPdf.render_pdf(
      url: "https://example.com/page",
      pdf_options: {
        landscape: false,
        scale: 1,
        paper_width: 8.5,
        paper_height: 11,
        margin_top: 0.4,
        margin_bottom: 0.4,
        margin_left: 0.4,
        margin_right: 0.4,
        display_header_footer: true,
        header_template: "<span class='title'></span>",
        footer_template: "<span class='pageNumber'></span>"
      }
    )