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_foundand add a file withinbuilder.html.erb:<%= @content %>
-
Create a file
app/views/not_found/not_found.html.erbwith 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.erbinapp/views/layouts.Alternatively, use
layout: falseand 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):