Rails 8 Minimum Browser Versions

Intro

Just a short post this time but wanted to share a great new feature in Rails 8 that just solved a problem I didn’t know I had! Minimum Browser Version.

Background

As you likely know I’ve been working on a few side projects and got an email from a user who said one didn’t work in Safari! Now, I use Safari a lot too, but quickly realised they were on an old version and getting this message in their browser console.

TypeError: Module specifier, 'application' does not start with "/", "'/", or "./".

I like to use the latest version of Rails in my side projects, and keep up with the new features like Importmaps and Propshaft, so I’m running against the HEAD of rails/rails main branch. The very latest!

The Problem

But one side effect of using the latest and greatest, in this case at least, is there’s a dependency on using more recent versions of the major browsers that support these features.

Safari, Chrome, Firefox and Opera only recently added support for importmaps, webp and some advanced css featues, so if a user is on an old or unsupported browser they may have all kinds of weird behaviours and experiences. Not good.

The Solution

In the past I’ve handled this for mobile device support and blocking old IE versions using the “browser” gem which is great but involved a lot of messy code and custom code. But not any more…

Enter the new “allowed_browser” helper in Rails 8! Now we can specify in our application controller what our browser support policy is, and then redirect any users visiting the site to a page that explains the issue and how they can update to a safer more modern browser.

We can simply set it to :modern and rails expands to the versions known to support webp, importmaps css nesting etc, namely { safari: 17.2, chrome: 120, firefox: 121, opera: 106, ie: false }

class ApplicationController < ActionController::Base
  allow_browser versions: :modern
end

We also need to add a new HTML file that users of unsupported browsers will be redirect to in public/406-unsupported-browser.html

Of course, if you want to get more specific about the browsers you support you can set them explicitly. For example the snippet below will allow all versions of Chrome and Opera, but no versions of “internet explorer” (ie), and Safari needs to be 16.4+ and Firefox 121+.

class ApplicationController < ActionController::Base
  allow_browser versions: { safari: 16.4, firefox: 121, ie: false }
end

You can also be more surgical about this by specifying by controller and action as shown below where we target just the CustomController show action and block opera and ie while lowering the supported versions of Safari.

class CustomController < ApplicationController
  allow_browser versions: { safari: 16.4, opera: false, ie: false }, only: :show
end

Crawlers ans SEO

One thing to be aware of is that allow_browser will likely block bots and crawlers, so any pages you really want them to be able to access should not have this option applied.

In my case, just the logged out home page and information pages should be crawlable since everything else requires a login, so I applied the allow_browser helper on a per-controller basis and not on ApplicationController.

Wrap Up

That’s it! A simple solution to a simple problem, provided in the way we know and love in Rails with grace, and simplicity. Love it!

As always, don’t hesitate to drop me a note via twitter or any other channels listed here.