Repository is archived
No release in over 3 years
Puppeteer based dynamic rendering for Rails applications
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

>= 0
>= 12.3.3
~> 3.0

Runtime

 Project Readme

N.B. The Bellroy technology team are transitioning away from Ruby as their primary programming language, and will not longer actively update this repository. Contact us if you'd like to take over as the primary maintainer.

dynamic-rendering-logo

Dynamic Rendering Gem Version CI Badge

Is your SEO performance being held hostage by frontend JavaScript UI frameworks? Dynamic rendering is a "workaround solution" (in the words of Google) to help make difficult to index JavaScript based content easier for search engine crawlers to understand by presenting them with a pre-rendered HTML snapshot of your page.

This gem implements dynamic rendering for Rails applications using Puppeteer via the Grover gem.

You can find out more about dynamic rendering in Google's article: https://developers.google.com/search/docs/guides/dynamic-rendering

Is this server-side rendering / SSR?

Kind of - Server-side rendering typically involves pre-rendering JavaScript elements of the page on the server within some isolated NodeJS environment and then having the client "re-hydrate" the DOM after loading. Dynamic rendering differs in that it's targeted specifically at crawler user agents and doesn't involve any "re-hydration" of the DOM, rather it's a static representation of the DOM, a snapshot of how the page looked in a headless Chrome instance.

How does this work?

diagram

Install

gem 'rails-dynamic-rendering'

Usage

Include the concern and then use enable_dynamic_rendering. Any controller action covered by the enable_dynamic_rendering call (which accepts all the same arguments as after_action) will based on the user agent choose to either just return the HTML with JS or choose to render the page in a headless Chrome instance & render back the serialized HTML with all JS removed.

class ApplicationController
  include DynamicRendering::ActsAsDynamicallyRenderable

  enable_dynamic_rendering only: :index, if: -> { some_condition_is_met? }

  def index
    @my_code = 'Does fancy stuff'
  end

  private

  def some_condition_is_met?
    true
  end
end

You can override the built in decision making thats used to determine whether a snapshot of the page should be returned by defining your own #request_suitable_for_dynamic_rendering? method. You might want to do this if you'd like to target other user agents:

def request_suitable_for_dynamic_rendering?
  request.user_agent.include? 'My Problematic Bot That Does Not Render JS Content'
end