@tubular/browser-check

2.1.0 • Public • Published

@Tubular Browser Check

(The Art of Giving Up Gracefully)

  • Check web browser’s level of JavaScript support (ES5, ES2015, ES2020, etc.).
  • Check for specific capabilities, like grid layout and WebGL2.
  • Check for minimum release version of various browsers, or rule out specific web browsers (like Internet Explorer) entirely.
  • Forward users to a friendly warning page when their browser doesn’t meet requirements.

As a web developer you likely know the pain of wanting to take advantage of useful new web browser features, but feeling like you have to hold back until very few users will be inconvenienced or excluded by browser incompatibilities which might arise from using the latest and greatest features that browsers have to offer.

Fortunately these days a majority of web users have switched to “evergreen” browsers which frequently self-update, allowing you to employ new features of JavaScript, HTML, and CSS with reasonable confidence.

There are still, however, people clinging to Windows 7 and IE. There are users with old desktops and mobile devices with limited capacity for updates and upgrades. Ideally, instead of leaving such users out in the cold, you selectively downgrade the capabilities of your websites a little, still providing most of the desired experience on older browsers — perhaps a little less stylishly, without all the bells and whistles.

There are times, however, when only relatively up-to-date web browsers will do. There need to be some cut-off points, below which you have to say to your users (much more diplomatically, of course) they are 💩 out of luck trying to get by with an older web browser.

Preferably this message of misfortune will be conveyed gracefully, not left to the user to deduce by way of frozen screens, confusing error messages, endlessly spinning spinners, jumbled page layouts, and other assorted technical failures. A polite, friendly, human-readable message explaining the problem, and perhaps even how to remedy the issue, is a much better way to go.

This is where @tubular/browser-check comes in.

This is a script written in lowest-common-denominator JavaScript (requiring nothing that cannot be done when constrained by the ancient standard of ES3) for assessing what a web browser is or is not capable of, providing an opportunity to redirect to an incompatibility message page when needed.

Using @tubular/browser-check, you can specify a minimum ES level (6/2015, 2016, 2017, etc.), particular features required (such as grid layout or WebGL), and/or minimum version numbers for popular web browsers. You can also rule out some web browsers (such as Internet Explorer and pre-Chromium Legacy Edge) entirely.

Installation/Use

@tubular/browser-check should be invoked via a <script> tag, before any other (possibly incompatible) JavaScript has a chance to run. This likely means being the first, or close to the first, script in the <head> section of a web page.

Using npm

npm i -D @tubular/browser-check

Since this code is meant to run as a pre-check process, and not to be a bundled part of a web application itself, it makes the most sense to install it under devDependencies, not dependencies, then copy either browser-check.js or browser-check.min.js from node_modules as part of your build process. For example, here is how I’m using the script in an Angular project, as seen in a snippet from my angular.json file:

{
  // ...
            "assets": [
              "src/favicon.ico",
              "src/assets",
              {
                "glob": "browser-check.min.js*",
                "input": "./node_modules/@tubular/browser-check/dist/",
                "output": "./assets/"
              }
            ],
  // ...
}

The script is pulled into the <head> section of the project’s index.html like this:

  <script src="assets/browser-check.min.js" type="text/javascript"
          id="tb-browser-check"
          data-bc-vers="0,79,79,13.1,605" data-bc-min-es="2017"
          data-bc-fail-url="assets/incompatible.html"></script>

The id is important so that very old browsers which don’t support querySelector can locate the script tag using getElementById. An alternative id value is "tubular-browser-check".

Using via unpkg.com

  <script src="https://unpkg.com/@tubular/browser-check/dist/browser-check.min.js" type="text/javascript"
          id="tb-browser-check"
          data-bc-vers="0,79,79,13.1,605" data-bc-min-es="2017"
          data-bc-fail-url="assets/incompatible.html"></script>

As always, the unpkg.com URL can include a specific npm package version if desired.

Internet Explorer issue

Older versions of IE can be buggy handling <base href=...> tags. As a result, it’s possible either the loading of this script, or the loading of your redirect page, might fail. The following code, placed after the <base> tag, and before the <script> tag, can fix that issue:

  <!--[if IE]><script type="text/javascript">
    (function() { // Fix for IE ignoring relative base tags.
        var baseTag = document.getElementsByTagName('base')[0];
        baseTag.href = baseTag.href + '';
    })();
  </script><![endif]-->

Options

Options are passed to @tubular/browser-check via various data-bc- attributes of the <script> tag.

data-bc-fail-url

This is the URL to which the user will be forwarded if the browser check fails. If this setting is omitted, @tubular/browser-check merely gathers information about a browser without taking any action.

In the event of a failed browser check, this URL will be appended with the parameter msg, containing a URL-encoded explanation of the reason why the browser check failed.

data-bc-min-es

This is the minimum acceptable ES compliance level. Nothing earlier than ES3 will be reported or detected. (Very few browsers should rate lower than ES2009 (ES5) these days.)

When set to a specific ES version (for example, 2018), @tubular/browser-check will stop checking for higher ES levels as soon as 2018 compliance is determined (although individual higher-level features can still be checked). If data-bc-min-es is set to 0, no ES level checking will be performed. If data-bc-min-es is set to -1, @tubular/browser-check will seek the highest level of support.

Not every ES feature is tested, of course, only a representative sample sufficient to determine the level of support with reasonable certainty.

ES2009 (ES5) tests
array2009 Array methods forEach, map, filter, reduce, and sort
object2009 Object methods create, freeze, and keys
ES2015 (ES6) tests
array2015 Array methods Array.from, keys, find, and findIndex
arrow Arrow functions
class class declarations
def_params Default function parameter values, e.g. function foo(a = 5)
destructuring Destructuring, e.g. let [a, b, c] = [1, 2, 3]
for_of for/of loops
let_const let and const keywords
map_set Map and Set classes
promise Native Promise
regex2015 Unicode-aware regular expressions, with the u flag
rest_param Rest function parameters, e.g. function foo(a, ...b)
string2015 String methods includes, startsWith, and endsWith
symbol Symbol objects are available
template Template strings, marked with back ticks, e.g. `You have ${count} cats.`
ES2016 tests
array2016 The array includes method
exp_op The ** exponentiation operator
ES2017 tests
async async/await support
object2017 Object.entries and Object.values
string2017 String methods padStart and padEnd
ES2018 tests
for_await for/await loops
promise_finally Promise finally method
regex2018 Support for look-behind, Unicode character classes, and the dot-all flag, e.g. /(?<=f)\p{L}+./su
rest_prop Rest syntax for object properties, e.g. let objClone = { ...obj }
ES2019 tests
array2019 Array flat and flapMap methods
catch_unbound catch clause in try/catch doesn’t need to be bound to a variable
object2019 Object.fromEntries method
string2019 String trimStart and trimEnd methods
ES2020 tests
all_settled Promise.allSettled method
bigint Native big integers, e.g. 12345678901234567890n
global_this globalThis is defined
null_ops Support for ?. optional chaining and ?? null-coalescing operators
ES2021 tests
logical_assigns Support for &&=, ||=, and ??= assignment operators
promise_any Promise.any method
underscores Underscores allowed in numeric constants, such as 86_400_000
ES2022 tests
private_fields Classes can have private fields, marked by #
private_accessors Classes can have private accessors, marked by #
static_fields Classes can have static fields
static_methods Classes can have static methods
static_init Classes can have static initializers
array_at Array at(index) function available
error_cause Error class can be initialized with a cause
has_own Object.hasOwn() function available
regex2022 Regular expression d flag, providing start and end positions for matched groups

data-bc-features

A comma-delimited list of browser features that you want to check and require. They can be any of the above ES feature tests, or from the list of other browser features below. Use the test other to compile a full list of all the features listed below that a browser supports.

audio Basic audio playback and processing
av_input Audio/video input, such as access to microphone and camera
canvas 2-D canvas drawing
canvas_text 2-D canvas drawing with text rendering
flex CSS flex layout
geo Geolocation services
grid CSS grid layout
local_storage Local storage support
video Video playback via HTML5 <video> tag
webgl Canvas WebGL support
webgl2 Canvas WebGL 2.0 support
workers Support for Web Workers

data-bc-vers

You can set this attribute to a comma-delimited list of minimum-supported browser version numbers, with the list of numbers being in this fixed order:

  • Internet Explorer
  • Legacy (pre-Chromium) Windows Edge
  • Chrome
  • Firefox
  • Safari
  • A minimum AppleWebKit version number for otherwise-unclassified non-Android, non-Linux browsers which specify an AppleWebKit version (quite likely running on iOS, using the same rendering engine as Safari).

You can use 0 as the version number for any browser you wish to completely disallow, and -1 for any browser you do not wish to check at all. (Any unspecified versions are treated as -1). Version numbers can include multiple dot-delimited version fields, such as 13.1 or 101.0.4951.64. Qualifiers such as -beta are not handled.

Ideally you can test for browser support without identifying particular browsers, using ES level and other feature checks alone. But sometimes particular browser quirks and bugs must be considered.

I fully support, for example, data-bc-vers="0,0" as a common starting point, completely giving up on supporting Internet Explorer and all the pre-Chromium versions of Microsoft’s Edge browser.

Many browsers, such as Opera, Samsung, and the latest versions of Microsoft Edge, are based on the same Chromium core engine as Google Chrome. These browsers are treated as variants of Chrome, and their Chrome version is what will matter, not their various browser-specific version numbers.

Please note: @tubular/browser-check does not employ a highly sophisticated browser identification system. Browser identification is an inexact science. The most accurate identification systems are much bigger and more elaborate than the quick-and-dirty classification scheme provided here. You might need to employ other means in addition to, or instead of, @tubular/browser-check if your needs for browser identification are more demanding.

data-bc-globals

Set this attribute to true (or simply add the attribute as a flag attribute with no value at all) if you would like to have @tubular/browser-check save its results in the global variable window.tb_bc_info. The information provided is, for example, as follows:

{
  browser: "Chrome", // Name or description of browser, possibly "Unrecognized"
  version: "101.0.4951.64", // Browser version, if determined
  es: 2021, // ES specification passed. 0 if never checked, minimum value of 3 if checked
  otherFeatures: "audio, av_input... workers", // Any tests successfully passed beyond the ES level check tests.
  msg: "" // If any tests have failed, the message describing that failure.
}

data-bc-googlebot

By default, this option is A(lways), allowing Googlebot access all the time. Option (N)ever turns Googlebot away in all circumstances. Option (I)gnore makes Googlebot immaterial, so that all other tests function as normal.

Skipping over browser check

Add the parameter tb-bc-skip=true to a URL to skip over browser checking when a web page loads.

Package Sidebar

Install

npm i @tubular/browser-check

Weekly Downloads

0

Version

2.1.0

License

MIT

Unpacked Size

77.1 kB

Total Files

8

Last publish

Collaborators

  • kshetline