Guide
BrowserX keeps the API of the browser gem, predicate for predicate. Installing it is swapping a gem; this page covers the rest.
Installation
gem "browserx"
BrowserX requires Ruby 3.3 or later. It is tested on Rails 8.0 and 8.1, and works without Rails.
Migrating from browser
Change one line of the Gemfile, nothing else:
- gem "browser"
+ gem "browserx"
The gem still loads with require "browser", still defines Browser, and require "browser/aliases" or require: "browser/browser" keep the meaning they had. BrowserX 1.0.0 is forked from browser 6.2.0 (dd88933), and a change that is not meant to change an answer is diffed against that version on the 20,328 user agents of the corpus.
To roll back, put gem "browser" back: 1.0.0 adds no option of its own, so no call site depends on BrowserX.
What comes next — a per-user-agent cache, bot categories, verified crawler IPs, Cloudflare headers and Client Hints — is tracked in the GitHub issues. Each will be an addition; no existing predicate changes meaning.
Usage
require "browser"
browser = Browser.new("Some User Agent", accept_language: "en-us")
Browser
browser.name # readable browser name
browser.version # major version number
browser.full_version
browser.to_s # the meta info joined by space
browser.meta # an array with several attributes
browser.known? # has the browser been successfully detected?
browser.unknown? # the browser wasn't detected
browser.webkit?
browser.webkit_full_version
browser.chromium_based?
browser.chrome?
browser.edge? # newest MS browser
browser.electron? # Electron Framework
browser.firefox?
browser.ie?
browser.ie?(6) # detect specific IE version
browser.ie?([">8", "<10"]) # detect specific IE (IE9)
browser.opera?
browser.opera_mini?
browser.safari?
browser.safari_webapp_mode?
browser.samsung_browser?
browser.core_media?
browser.duck_duck_go?
browser.epiphany?
browser.nokia?
browser.phantom_js?
browser.qq?
browser.quicktime?
browser.sougou_browser?
browser.sputnik?
browser.uc_browser?
browser.wechat?
browser.weibo?
browser.yandex?
Version predicates take a version or a list of constraints, so a “modern browser” check is a method of yours:
def modern_browser?(browser)
[
browser.chrome?(">= 65"),
browser.safari?(">= 10"),
browser.firefox?(">= 52"),
browser.ie?(">= 11") && !browser.compatibility_view?,
browser.edge?(">= 15"),
browser.opera?(">= 50"),
browser.facebook? &&
browser.safari_webapp_mode? &&
browser.webkit_full_version.to_i >= 602
].any?
end
Bots
browser.bot?
browser.bot.name
browser.bot.search_engine?
browser.bot.why? # which matcher detected this user agent as a bot
Browser::Bot.why?(user_agent)
How a bot is detected, and how to change the lists, is on the Bots page.
Device
browser.device
browser.device.id
browser.device.name
browser.device.unknown?
browser.device.mobile?
browser.device.tablet?
browser.device.tv?
browser.device.console?
browser.device.ipad?
browser.device.iphone?
browser.device.ipod_touch?
browser.device.kindle?
browser.device.kindle_fire?
browser.device.silk?
browser.device.surface?
browser.device.samsung?
browser.device.blackberry_playbook?
browser.device.nintendo?
browser.device.switch?
browser.device.wii?
browser.device.wiiu?
browser.device.playstation?
browser.device.ps3?
browser.device.ps4?
browser.device.psp?
browser.device.vita?
browser.device.xbox?
browser.device.xbox_360?
browser.device.xbox_one?
Platform
browser.platform
browser.platform.id
browser.platform.name
browser.platform.version # e.g. 9 (for iOS 9)
browser.platform.unknown?
browser.platform.adobe_air?
browser.platform.android?
browser.platform.android?(4.2) # detect Android Jelly Bean 4.2
browser.platform.android_app? # detect webview in an Android app
browser.platform.android_webview? # alias for android_app?
browser.platform.blackberry?
browser.platform.blackberry?(10) # detect specific BlackBerry version
browser.platform.chrome_os?
browser.platform.firefox_os?
browser.platform.ios?
browser.platform.ios?(9) # detect specific iOS version
browser.platform.ios_app? # detect webview in an iOS app
browser.platform.ios_webview? # alias for ios_app?
browser.platform.kai_os?
browser.platform.linux?
browser.platform.mac?
browser.platform.windows?
browser.platform.windows_xp?
browser.platform.windows_vista?
browser.platform.windows7?
browser.platform.windows8?
browser.platform.windows8_1?
browser.platform.windows10?
browser.platform.windows_rt?
browser.platform.windows_mobile?
browser.platform.windows_phone?
browser.platform.windows_touchscreen_desktop?
browser.platform.windows_wow64?
browser.platform.windows_x64?
browser.platform.windows_x64_inclusive?
The full lists live in lib/browser/platform.rb and lib/browser/device.rb.
Aliases
To call browser.mobile? and browser.tablet? on the base object, include the aliases:
require "browser/aliases"
Browser::Base.include(Browser::Aliases)
Browser.new("Some user agent").mobile? #=> false
Options
| Setting | Default | What it does |
|---|---|---|
accept_language: | nil | The Accept-Language header, passed to Browser.new; parsed into browser.accept_language. |
Browser.user_agent_size_limit | 2048 | Largest user agent accepted, in bytes. A larger one raises Browser::Error. |
Browser.accept_language_size_limit | 2048 | Largest Accept-Language header accepted, in bytes. A larger one raises Browser::Error. |
Browser::Bot.matchers | three built-in matchers | Callables deciding whether a user agent is a bot. See Bots. |
Browser::Bot.bots | bots.yml | Known bots, keyed by a lowercase substring of their user agent. |
Browser::Bot.search_engines | search_engines.yml | Bots answering bot.search_engine?. |
Browser::Bot.bot_exceptions | bot_exceptions.yml | Substrings that are never a bot, even when a matcher says so. |
Browser.user_agent_size_limit = 4096
Browser.accept_language_size_limit = 4096
Rails
The Gemfile line is enough: a railtie adds a browser helper to controllers and views, built from the request’s User-Agent and Accept-Language headers.
<% if browser.ie?(6) %>
<p class="disclaimer">You're running an older IE version. Please update it!</p>
<% end %>
To use BrowserX in a Rails app without adding the helper to controllers, load only the library:
gem "browserx", require: "browser/browser"
Middleware
Browser::Middleware redirects user agents from a Rack stack:
use Browser::Middleware do
redirect_to "/upgrade" if browser.ie?
end
In Rails, route helpers work from an initializer (config/initializers/browser.rb), and request gives the Rack::Request:
Rails.configuration.middleware.use Browser::Middleware do
redirect_to upgrade_path if browser.ie? && request.env["PATH_INFO"] != "/exclude_me"
end
Accept-Language
browser.accept_language is an array of languages, sorted by quality from highest to lowest. A missing quality means 1.0; a quality of zero means the language is not accepted.
language = Browser.new(user_agent, accept_language: "en-us").accept_language.first
language.code #=> "en"
language.region #=> "US"
language.full #=> "en-US"
language.quality #=> 1.0
language.name #=> "English/United States"
Internet Explorer and Safari
Internet Explorer. In compatibility view, IE8 and later run as an older version. version and full_version return the navigator’s version; msie_version and msie_full_version return the engine’s.
browser.version #=> 11
browser.full_version #=> 11.0
browser.msie_version #=> 7
browser.msie_full_version #=> 7.0
browser.compatibility_view? #=> true
Safari. iOS webviews and web apps are not Safari. Combine platform and WebKit detection instead:
browser = Browser.new("Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405")
browser.safari? #=> false
browser.webkit? #=> true
browser.platform.ios? #=> true