Update banner widget

One script tag. Visitors on outdated browsers see a small dismissible notice linking to mybrowser.org, where they can update — or pick a different browser. Everyone else sees nothing at all.

Add it to your site

Paste this anywhere in your page — head or body, order does not matter. The script loads asynchronously and never blocks rendering:

<script src="https://mybrowser.org/widget.js" async></script>

Optional speed-up: add this line anywhere before the script — it warms up the connection while your page is still parsing, so the check completes ~100–300 ms sooner on mobile networks. Everything works exactly the same without it.

<link rel="preconnect" href="https://mybrowser.org">

Changing an option above rewrites the snippet — attributes are only added when they differ from the defaults. Tip: data-threshold="2" or "3" makes the banner extra quiet, so nobody is flagged in the middle of a normal release rollout. (One exception: end-of-life browsers such as Internet Explorer are always flagged, whatever the threshold.)

Live preview

See exactly what your visitors would get. The preview uses the widget’s built-in test mode (data-test="1") to force the banner even if your browser is current.

The banner appears fixed at the top or bottom of this page, using the position and language chosen above.

All attributes

AttributeValuesDefaultWhat it does
data-position top | bottom top Where the banner is fixed on the screen.
data-stack auto | push | over auto Top-position behavior around your own fixed bars. auto detects a full-width fixed bar at the top of your page (a navigation or cookie-consent bar) and stacks the banner just below it, so nothing of yours becomes unclickable. push puts the banner at the very top and pushes your page — including a fixed navigation bar — down below it, restoring everything when the banner is dismissed. over puts the banner at the very top and overlays whatever is there.
data-lang any language code (38 built in: en, bg, de, fr, es, it, pt, ru, uk, tr, ar, zh, ja …) auto Language of the banner text. When omitted, the visitor’s own browser language is used automatically (their Accept-Language / navigator.language — read only to pick the text, never stored). Unknown languages fall back to English. Right-to-left languages (Arabic, Hebrew, Farsi) get a mirrored layout.
data-threshold 1–10 1 How many major versions behind the latest stable release a browser must be before the banner shows. 2–3 is a good low-noise choice. Values above 10 are treated as 10. Exception: end-of-life browsers with no current release to compare against (Internet Explorer) are always flagged, regardless of this setting.
data-dismiss-days 0–365 30 After a visitor dismisses the banner (or clicks Update), it stays hidden for this many days. Values above 365 are treated as 365; non-numeric values fall back to 30. 0 is mainly for testing: the banner may reappear on the very next page view.
data-test 1 off Forces the banner to show regardless of the visitor’s browser — for previewing your setup. Opening any page with #mbw-test in the URL does the same, so you can verify a live site without editing it.
data-api URL https://mybrowser.org/api Detection endpoint. Override it to test locally or run the whole thing self-hosted.

Custom styles

The banner ships with a careful default look (WCAG AA contrast, system fonts). If you want it to match your site, define any of these CSS variables on :root — the widget reads them when the banner renders and applies them for you. Anything you don’t set keeps its default. Invalid values are ignored.

<style>
  :root {
    --mbw-bg: #1f2430;            /* banner background */
    --mbw-text: #e6e9f0;          /* message text color */
    --mbw-border: 1px solid #3d4560;  /* banner edge */
    --mbw-button-bg: #4f8cff;     /* update button background */
    --mbw-button-text: #ffffff;   /* update button text */
    --mbw-close: #aab2c5;         /* close (×) color */
    --mbw-radius: 999px;          /* update button corner radius */
    --mbw-font: Georgia, serif;   /* font family */
    --mbw-z: 99999;               /* stacking order */
  }
</style>

Two notes: color contrast becomes your responsibility once you override the defaults (please keep the text readable — the banner is meant to help people), and custom styles change nothing else: the widget still stores nothing, tracks nobody, and fails silently.

How it decides

Your visitor’s browser makes one small request to our API. The server identifies the browser from the request’s own User-Agent and low-entropy Client Hints headers — the same engine behind mybrowser.org — and compares the major version against the current stable releases (last refreshed 2026-09-25, updated weekly). The widget itself contains zero version logic, so it never goes stale in your visitors’ caches.

It is built to fail quiet, never loud: bots, unknown browsers, unrecognized versions and Firefox ESR releases all get no banner. A false “you are outdated” on your site is the one thing this widget refuses to do.

Privacy

Compatibility & security notes

The script is plain ES5 with no dependencies and runs on IE10+ and Safari 6+. One practical limit applies: devices that no longer trust Let's Encrypt's certificate root (Android 7.0 and below) cannot reach our HTTPS API, so on those the widget is a guaranteed silent no-op — as it is on any other failure. A script failure can never break your page — the widget simply does nothing. Total size is about 4.5 KB compressed.

Running a Content-Security-Policy? For an allowlist policy, allow script-src https://mybrowser.org and connect-src https://mybrowser.org. For a nonce-based policy ('nonce-…' with 'strict-dynamic'), host allowlists are ignored by design — instead add your per-request nonce to the script tag itself, and keep connect-src https://mybrowser.org for the version check:

<script src="https://mybrowser.org/widget.js" async nonce="YOUR_REQUEST_NONCE"></script>

Nothing else needs allowing: the banner styles itself through the CSSOM (not subject to style-src), never creates further scripts, and the optional preconnect hint is not gated by CSP.

Two layout notes: the banner uses z-index 2147483000, deliberately below the maximum — your own overlays with a higher z-index at the same screen edge (cookie or consent bars at 2147483647 are common) will cover it, so keep such overlays at or below 2147483000 or place the banner at the other edge. And if your page applies transform, filter or perspective to <body>, the widget attaches the banner to <html> instead so it stays fixed to the viewport — avoid such styles on <html> itself, where no fallback exists.

The banner is accessible: a labelled region, real keyboard-operable buttons, WCAG AA contrast, no focus stealing and no auto-hide. It also maintains scroll-padding while visible, so keyboard focus on your page is never scrolled underneath it — embedding the banner does not affect your site’s WCAG 2.2 AA conformance (SC 2.4.11, Focus Not Obscured).

← What browser am I using?