Give builder.io a chance to respond to paths that you don't have a route for before serving up a 404 page:
-
In
Gemfile
, addgem 'rack-cors'
andbundle
. -
In
config/application.rb
, add:config.middleware.insert_before 0, Rack::Cors do allow do origins '*' resource '*', headers: :any, methods: [:get, :post, :options] end end
-
In
config/application.rb
, add:config.exceptions_app = self.routes
-
rails generate controller not_found builder
-
In
config/routes.rb
, replace the generated route with:match "/404", to: "not_found#builder", via: :all
-
In
app/controllers/not_found_controller.rb
, enhance the action:class NotFoundController < ApplicationController def builder builder_url = "https://builder.io/api/v1/html/page?url=#{request.original_url}&apiKey=#{ENV.fetch("BUILDER_API_KEY")}" builder_response = HTTParty.get(builder_url, follow_redirects: true) if builder_response.code != 404 data = JSON.parse(builder_response.body).fetch("data") @content = data.fetch("html").html_safe else render :not_found, status: 404 end end end
- This assumes you're storing your builder.io API key in an environment variable.
- This assumes you've included httparty for making requests.
-
Create a folder
app/views/not_found
and add a file withinbuilder.html.erb
:<%= @content %>
-
Create a file
app/views/not_found/not_found.html.erb
with your usual 404 content. If you're copying in an entire document from a staticpublic/404.html
, then you may want to:render :not_found, status: 404, layout: false
-
If you've got one,
rm public/404.html
. -
Test locally: in
config/environments/development.rb
,config.consider_all_requests_local = false
-
Use a layout specifically for builder.io pages if you want to:
render layout: "builder"
And then create
builder.html.erb
inapp/views/layouts
.Alternatively, use
layout: false
and put your entire document, including<html>
,<head>
, etc, infound.html.erb
.
This is great, thanks for making this gist, only note is to hit the cdn directly (cdn.builder.io):