/*!
* Bowser - a browser detector
- * https://github.com/lancedikson/bowser
+ * https://github.com/bowser-js/bowser
* MIT License | (c) Dustin Diaz 2012-2015
* MIT License | (c) Denis Demchenko 2015-2019
*/
@@ -72,33 +72,49 @@ class Bowser {
* Creates a {@link Parser} instance
*
* @param {String} UA UserAgent string
- * @param {Boolean} [skipParsing=false] Will make the Parser postpone parsing until you ask it
- * explicitly. Same as `skipParsing` for {@link Parser}.
+ * @param {Boolean|Object} [skipParsingOrHints=false] Either a boolean to skip parsing,
+ * or a ClientHints object (navigator.userAgentData)
+ * @param {Object} [clientHints] User-Agent Client Hints data (navigator.userAgentData)
* @returns {Parser}
* @throws {Error} when UA is not a String
*
* @example
* const parser = Bowser.getParser(window.navigator.userAgent);
* const result = parser.getResult();
+ *
+ * @example
+ * // With User-Agent Client Hints
+ * const parser = Bowser.getParser(
+ * window.navigator.userAgent,
+ * window.navigator.userAgentData
+ * );
*/
- static getParser(UA, skipParsing = false) {
+ static getParser(UA, skipParsingOrHints = false, clientHints = null) {
if (typeof UA !== 'string') {
throw new Error('UserAgent should be a string');
}
- return new Parser(UA, skipParsing);
+ return new Parser(UA, skipParsingOrHints, clientHints);
}
/**
* Creates a {@link Parser} instance and runs {@link Parser.getResult} immediately
*
- * @param UA
+ * @param {String} UA UserAgent string
+ * @param {Object} [clientHints] User-Agent Client Hints data (navigator.userAgentData)
* @return {ParsedResult}
*
* @example
* const result = Bowser.parse(window.navigator.userAgent);
+ *
+ * @example
+ * // With User-Agent Client Hints
+ * const result = Bowser.parse(
+ * window.navigator.userAgent,
+ * window.navigator.userAgentData
+ * );
*/
- static parse(UA) {
- return (new Parser(UA)).getResult();
+ static parse(UA, clientHints = null) {
+ return (new Parser(UA, clientHints)).getResult();
}
static get BROWSER_MAP() {
@@ -133,7 +149,7 @@ export default Bowser;
diff --git a/docs/global.html b/docs/global.html
index 3f2948f..71efd2e 100644
--- a/docs/global.html
+++ b/docs/global.html
@@ -27,7 +27,7 @@
@@ -136,7 +136,7 @@
Source:
@@ -313,7 +313,7 @@
Source:
@@ -490,7 +490,7 @@
Source:
@@ -668,7 +668,7 @@
Source:
@@ -827,7 +827,7 @@
Source:
@@ -867,7 +867,7 @@
- Get short version/alias for a browser name
+ Get browser name for a short version/alias
@@ -880,7 +880,7 @@
Example
- getBrowserAlias('edge') // Microsoft Edge
+ getBrowserTypeByAlias('edge') // Microsoft Edge
@@ -1175,7 +1175,7 @@
Source:
@@ -1538,7 +1538,7 @@
Source:
@@ -1697,7 +1697,7 @@
Source:
@@ -2065,6 +2065,323 @@
+ClientHints
+
+
+
+
+
+
+
+
+ - Source:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Properties:
+
+
+
+
+
+
+
+ Name
+
+
+ Type
+
+
+ Attributes
+
+
+
+
+ Description
+
+
+
+
+
+
+
+
+ brands
+
+
+
+
+
+Array.<{brand: string, version: string}>
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+ Array of brand objects
+
+
+
+
+
+
+ mobile
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+ Whether the device is mobile
+
+
+
+
+
+
+ platform
+
+
+
+
+
+string
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+ Platform name (e.g., "Windows", "macOS")
+
+
+
+
+
+
+ platformVersion
+
+
+
+
+
+string
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+ Platform version
+
+
+
+
+
+
+ architecture
+
+
+
+
+
+string
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+ CPU architecture
+
+
+
+
+
+
+ model
+
+
+
+
+
+string
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+ Device model
+
+
+
+
+
+
+ wow64
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+ Whether running under WoW64
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Type:
+
+ -
+
+Object
+
+
+
+
+
+
+
+
+
+
+
+
ParsedResult
@@ -2076,7 +2393,7 @@
Source:
@@ -2711,7 +3028,7 @@ like "iPhone" or "Kindle Fire HD 7"
diff --git a/docs/index.html b/docs/index.html
index f9cb242..98d37a5 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -27,7 +27,7 @@
@@ -65,19 +65,23 @@
Multi-platform. It's browser- and node-ready, so you can use it in any environment.
Don't hesitate to support the project on Github or OpenCollective if you like it ❤️ Also, contributors are always welcome!
-
+
Contents
Overview
The library is made to help to detect what browser your user has and gives you a convenient API to filter the users somehow depending on their browsers. Check it out on this page: https://bowser-js.github.io/bowser-online/.
⚠️ Version 2.0 breaking changes ⚠️
-Version 2.0 has drastically changed the API. All available methods are on the docs page.
-For legacy code, check out the 1.x branch and install it through npm install bowser@1.9.4.
+Version 2.0 has drastically changed the API. All available methods are on the docs page.
+For legacy code, check out the 1.x branch and install it through npm install bowser@1.9.4.
Use cases
First of all, require the library. This is a UMD Module, so it will work for AMD, TypeScript, ES6, and CommonJS module systems.
const Bowser = require("bowser"); // CommonJS
@@ -98,6 +102,53 @@ As the result, you get a ES5 version of bowser with babel-polyfill
console.log(`The current browser name is "${browser.getBrowserName()}"`);
// The current browser name is "Internet Explorer"
+Using User-Agent Client Hints
+Modern browsers support User-Agent Client Hints, which provide a more privacy-friendly and structured way to access browser information. Bowser can use Client Hints data to improve browser detection accuracy.
+// Pass Client Hints as the second parameter
+const browser = Bowser.getParser(
+ window.navigator.userAgent,
+ window.navigator.userAgentData
+);
+
+console.log(`The current browser name is "${browser.getBrowserName()}"`);
+// More accurate detection using Client Hints
+
+Working with Client Hints
+Bowser provides methods to access and query Client Hints data:
+const browser = Bowser.getParser(
+ window.navigator.userAgent,
+ window.navigator.userAgentData
+);
+
+// Get the full Client Hints object
+const hints = browser.getHints();
+// Returns the ClientHints object or null if not provided
+
+// Check if a specific brand exists
+if (browser.hasBrand('Google Chrome')) {
+ console.log('This is Chrome!');
+}
+
+// Get the version of a specific brand
+const chromeVersion = browser.getBrandVersion('Google Chrome');
+console.log(`Chrome version: ${chromeVersion}`);
+
+The Client Hints object structure:
+{
+ brands: [
+ { brand: 'Google Chrome', version: '131' },
+ { brand: 'Chromium', version: '131' },
+ { brand: 'Not_A Brand', version: '24' }
+ ],
+ mobile: false,
+ platform: 'Windows',
+ platformVersion: '15.0.0',
+ architecture: 'x86',
+ model: '',
+ wow64: false
+}
+
+Note: Client Hints improve detection for browsers like DuckDuckGo and other Chromium-based browsers that may have similar User-Agent strings. When Client Hints are not provided, Bowser falls back to standard User-Agent string parsing.
or
const browser = Bowser.getParser(window.navigator.userAgent);
console.log(browser.getBrowser());
@@ -131,6 +182,11 @@ console.log(browser.getBrowser());
}
}
+You can also use Bowser.parse() with Client Hints:
+console.log(Bowser.parse(window.navigator.userAgent, window.navigator.userAgentData));
+
+// Same output structure, but with enhanced detection from Client Hints
+
Filtering browsers
You could want to filter some particular browsers to provide any special support for them or make any workarounds.
It could look like this:
@@ -176,8 +232,8 @@ list of aliases can be found in the file.
Contributors
Code Contributors
-This project exists thanks to all the people who contribute. [Contribute].
-
+This project exists thanks to all the people who contribute. [Contribute].
+
Financial Contributors
Become a financial contributor and help us sustain our community. [Contribute]
Individuals
@@ -210,7 +266,7 @@ list of aliases can be found in the file.
diff --git a/docs/parser.js.html b/docs/parser.js.html
index 11adc02..c7d2e0c 100644
--- a/docs/parser.js.html
+++ b/docs/parser.js.html
@@ -27,7 +27,7 @@
@@ -48,6 +48,17 @@ import platformParsersList from './parser-platforms.js';
import enginesParsersList from './parser-engines.js';
import Utils from './utils.js';
+/**
+ * @typedef {Object} ClientHints
+ * @property {Array<{brand: string, version: string}>} [brands] Array of brand objects
+ * @property {boolean} [mobile] Whether the device is mobile
+ * @property {string} [platform] Platform name (e.g., "Windows", "macOS")
+ * @property {string} [platformVersion] Platform version
+ * @property {string} [architecture] CPU architecture
+ * @property {string} [model] Device model
+ * @property {boolean} [wow64] Whether running under WoW64
+ */
+
/**
* The main class that arranges the whole parsing process.
*/
@@ -56,21 +67,32 @@ class Parser {
* Create instance of Parser
*
* @param {String} UA User-Agent string
- * @param {Boolean} [skipParsing=false] parser can skip parsing in purpose of performance
- * improvements if you need to make a more particular parsing
- * like {@link Parser#parseBrowser} or {@link Parser#parsePlatform}
+ * @param {Boolean|ClientHints} [skipParsingOrHints=false] Either a boolean to skip parsing,
+ * or a ClientHints object containing User-Agent Client Hints data
+ * @param {ClientHints} [clientHints] User-Agent Client Hints data (navigator.userAgentData)
*
* @throw {Error} in case of empty UA String
*
* @constructor
*/
- constructor(UA, skipParsing = false) {
+ constructor(UA, skipParsingOrHints = false, clientHints = null) {
if (UA === void (0) || UA === null || UA === '') {
throw new Error("UserAgent parameter can't be empty");
}
this._ua = UA;
+ // Handle overloaded constructor: (UA, clientHints) or (UA, skipParsing, clientHints)
+ let skipParsing = false;
+ if (typeof skipParsingOrHints === 'boolean') {
+ skipParsing = skipParsingOrHints;
+ this._hints = clientHints;
+ } else if (skipParsingOrHints != null && typeof skipParsingOrHints === 'object') {
+ this._hints = skipParsingOrHints;
+ } else {
+ this._hints = null;
+ }
+
/**
* @typedef ParsedResult
* @property {Object} browser
@@ -100,6 +122,65 @@ class Parser {
}
}
+ /**
+ * Get Client Hints data
+ * @return {ClientHints|null}
+ *
+ * @public
+ * @example
+ * const parser = Bowser.getParser(UA, clientHints);
+ * const hints = parser.getHints();
+ * console.log(hints.platform); // 'Windows'
+ * console.log(hints.mobile); // false
+ */
+ getHints() {
+ return this._hints;
+ }
+
+ /**
+ * Check if a brand exists in Client Hints brands array
+ * @param {string} brandName The brand name to check for
+ * @return {boolean}
+ *
+ * @public
+ * @example
+ * const parser = Bowser.getParser(UA, clientHints);
+ * if (parser.hasBrand('Google Chrome')) {
+ * console.log('Chrome detected!');
+ * }
+ */
+ hasBrand(brandName) {
+ if (!this._hints || !Array.isArray(this._hints.brands)) {
+ return false;
+ }
+ const brandLower = brandName.toLowerCase();
+ return this._hints.brands.some(
+ b => b.brand && b.brand.toLowerCase() === brandLower,
+ );
+ }
+
+ /**
+ * Get brand version from Client Hints
+ * @param {string} brandName The brand name to get version for
+ * @return {string|undefined}
+ *
+ * @public
+ * @example
+ * const parser = Bowser.getParser(UA, clientHints);
+ * const version = parser.getBrandVersion('Google Chrome');
+ * console.log(version); // '131'
+ */
+ getBrandVersion(brandName) {
+ if (!this._hints || !Array.isArray(this._hints.brands)) {
+ return undefined;
+ }
+ const brandLower = brandName.toLowerCase();
+ const brand = this._hints.brands.find(
+ b => b.brand && b.brand.toLowerCase() === brandLower,
+ );
+ return brand ? brand.version : undefined;
+ }
+
/**
* Get UserAgent string of current Parser instance
* @return {String} User-Agent String of the current <Parser> object
@@ -131,7 +212,7 @@ class Parser {
return _browser.test(this);
}
- if (_browser.test instanceof Array) {
+ if (Array.isArray(_browser.test)) {
return _browser.test.some(condition => this.test(condition));
}
@@ -139,7 +220,7 @@ class Parser {
});
if (browserDescriptor) {
- this.parsedResult.browser = browserDescriptor.describe(this.getUA());
+ this.parsedResult.browser = browserDescriptor.describe(this.getUA(), this);
}
return this.parsedResult.browser;
@@ -214,7 +295,7 @@ class Parser {
return _os.test(this);
}
- if (_os.test instanceof Array) {
+ if (Array.isArray(_os.test)) {
return _os.test.some(condition => this.test(condition));
}
@@ -290,7 +371,7 @@ class Parser {
return _platform.test(this);
}
- if (_platform.test instanceof Array) {
+ if (Array.isArray(_platform.test)) {
return _platform.test.some(condition => this.test(condition));
}
@@ -341,7 +422,7 @@ class Parser {
return _engine.test(this);
}
- if (_engine.test instanceof Array) {
+ if (Array.isArray(_engine.test)) {
return _engine.test.some(condition => this.test(condition));
}
@@ -452,7 +533,7 @@ class Parser {
/**
* Check if the browser name equals the passed string
- * @param browserName The string to compare with the browser name
+ * @param {string} browserName The string to compare with the browser name
* @param [includingAlias=false] The flag showing whether alias will be included into comparison
* @returns {boolean}
*/
@@ -503,14 +584,29 @@ class Parser {
) > -1;
}
+ /**
+ * Check if the OS name equals the passed string
+ * @param {string} osName The string to compare with the OS name
+ * @returns {boolean}
+ */
isOS(osName) {
return this.getOSName(true) === String(osName).toLowerCase();
}
+ /**
+ * Check if the platform type equals the passed string
+ * @param {string} platformType The string to compare with the platform type
+ * @returns {boolean}
+ */
isPlatform(platformType) {
return this.getPlatformType(true) === String(platformType).toLowerCase();
}
+ /**
+ * Check if the engine name equals the passed string
+ * @param {string} engineName The string to compare with the engine name
+ * @returns {boolean}
+ */
isEngine(engineName) {
return this.getEngineName(true) === String(engineName).toLowerCase();
}
@@ -552,7 +648,7 @@ export default Parser;
diff --git a/docs/utils.js.html b/docs/utils.js.html
index 31a90df..72405fe 100644
--- a/docs/utils.js.html
+++ b/docs/utils.js.html
@@ -27,7 +27,7 @@
@@ -357,10 +357,10 @@ export default class Utils {
}
/**
- * Get short version/alias for a browser name
+ * Get browser name for a short version/alias
*
* @example
- * getBrowserAlias('edge') // Microsoft Edge
+ * getBrowserTypeByAlias('edge') // Microsoft Edge
*
* @param {string} browserAlias
* @return {string}
@@ -383,7 +383,7 @@ export default class Utils {
diff --git a/src/parser.js b/src/parser.js
index 0f51189..1c2a5bf 100644
--- a/src/parser.js
+++ b/src/parser.js
@@ -83,6 +83,11 @@ class Parser {
* @return {ClientHints|null}
*
* @public
+ * @example
+ * const parser = Bowser.getParser(UA, clientHints);
+ * const hints = parser.getHints();
+ * console.log(hints.platform); // 'Windows'
+ * console.log(hints.mobile); // false
*/
getHints() {
return this._hints;
@@ -94,6 +99,11 @@ class Parser {
* @return {boolean}
*
* @public
+ * @example
+ * const parser = Bowser.getParser(UA, clientHints);
+ * if (parser.hasBrand('Google Chrome')) {
+ * console.log('Chrome detected!');
+ * }
*/
hasBrand(brandName) {
if (!this._hints || !Array.isArray(this._hints.brands)) {
@@ -111,6 +121,10 @@ class Parser {
* @return {string|undefined}
*
* @public
+ * @example
+ * const parser = Bowser.getParser(UA, clientHints);
+ * const version = parser.getBrandVersion('Google Chrome');
+ * console.log(version); // '131'
*/
getBrandVersion(brandName) {
if (!this._hints || !Array.isArray(this._hints.brands)) {
(static) getParser(UA, skipParsingopt) → {Parser}
+(static) getParser(UA, skipParsingOrHintsopt, clientHintsopt) → {Parser}
@@ -90,7 +90,7 @@Example
+Examples
const parser = Bowser.getParser(window.navigator.userAgent);
const result = parser.getResult();
+ // With User-Agent Client Hints
+const parser = Bowser.getParser(
+ window.navigator.userAgent,
+ window.navigator.userAgentData
+);
+
@@ -213,13 +219,16 @@ const result = parser.getResult();
skipParsingskipParsingOrHintsWill make the Parser postpone parsing until you ask it
-explicitly. Same as skipParsing for Parser.
Either a boolean to skip parsing, +or a ClientHints object (navigator.userAgentData)
clientHints+ + + + + +
null
+
+ User-Agent Client Hints data (navigator.userAgentData)
skipParsing for Parser(static) parse(UA) → {ParsedResult}
+ (static) parse(UA, clientHintsopt) → {ParsedResult}
@@ -335,7 +383,7 @@ explicitly. Same asskipParsing for ParserSource:
skipParsing for ParserExample
+ Examples
const result = Bowser.parse(window.navigator.userAgent);
+ // With User-Agent Client Hints
+const result = Bowser.parse(
+ window.navigator.userAgent,
+ window.navigator.userAgentData
+);
+
@@ -406,8 +460,12 @@ explicitly. Same as skipParsing for ParserType
+ skipParsing for Parser
+
+String
+
+
+
+ UserAgent string
clientHints+ + + + + +
null
+
+ User-Agent Client Hints data (navigator.userAgentData)
skipParsing for Parser
diff --git a/docs/Parser.html b/docs/Parser.html
index 3f4865b..cdbcbe9 100644
--- a/docs/Parser.html
+++ b/docs/Parser.html
@@ -27,7 +27,7 @@
Constructor
-new Parser(UA, skipParsingopt)
+new Parser(UA, skipParsingOrHintsopt, clientHintsopt)
@@ -75,7 +75,7 @@skipParsingskipParsingOrHintsparser can skip parsing in purpose of performance -improvements if you need to make a more particular parsing -like Parser#parseBrowser or Parser#parsePlatform
Either a boolean to skip parsing, +or a ClientHints object containing User-Agent Client Hints data
clientHints+ + + + + +
null
+
+ User-Agent Client Hints data (navigator.userAgentData)
-
+
+
+
- Source: +
- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Get brand version from Client Hints
+Example
+ +const parser = Bowser.getParser(UA, clientHints);
+const version = parser.getBrandVersion('Google Chrome');
+console.log(version); // '131'
+
+
+
+
+ Parameters:
+ + +| Name | + + +Type | + + + + + +Description | +
|---|---|---|
brandName |
+
+
+ + + +string + + + + | + + + + + +The brand name to get version for |
+
Returns:
+ + + + +-
+
- + Type + +
- + +string +| + +undefined + + + +
getBrowser() → {Object}
@@ -289,7 +494,7 @@ like Parser#parseBrowser or Source:-
+
+
+
- Source: +
- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Get Client Hints data
+Example
+ +const parser = Bowser.getParser(UA, clientHints);
+const hints = parser.getHints();
+console.log(hints.platform); // 'Windows'
+console.log(hints.mobile); // false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Returns:
+ + + + +-
+
- + Type + +
- + +ClientHints +| + +null + + + +
getOS() → {Object}
@@ -826,7 +1147,7 @@ like Parser#parseBrowser or Source:-
+
+
+
- Source: +
- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Check if a brand exists in Client Hints brands array
+Example
+ +const parser = Bowser.getParser(UA, clientHints);
+if (parser.hasBrand('Google Chrome')) {
+ console.log('Chrome detected!');
+}
+
+
+
+
+ Parameters:
+ + +| Name | + + +Type | + + + + + +Description | +
|---|---|---|
brandName |
+
+
+ + + +string + + + + | + + + + + +The brand name to check for |
+
Returns:
+ + + + +-
+
- + Type + +
- + +boolean + + + +
is(anything, includingAliasopt) → {Boolean}
@@ -1712,7 +2195,7 @@ like Parser#parseBrowser or Source:Returns:
+ + + + +-
+
- + Type + +
- + +boolean + + + +
isEngine(engineName) → {boolean}
+ + + + + + +-
+
+
+
- Source: +
- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Check if the engine name equals the passed string
+Parameters:
+ + +| Name | + + +Type | + + + + + +Description | +
|---|---|---|
engineName |
+
+
+ + + +string + + + + | + + + + + +The string to compare with the engine name |
+
Returns:
+ + + + +-
+
- + Type + +
- + +boolean + + + +
isOS(osName) → {boolean}
+ + + + + + +-
+
+
+
- Source: +
- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Check if the OS name equals the passed string
+Parameters:
+ + +| Name | + + +Type | + + + + + +Description | +
|---|---|---|
osName |
+
+
+ + + +string + + + + | + + + + + +The string to compare with the OS name |
+
Returns:
+ + + + +-
+
- + Type + +
- + +boolean + + + +
isPlatform(platformType) → {boolean}
+ + + + + + +-
+
+
+
- Source: +
- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Check if the platform type equals the passed string
+Parameters:
+ + +| Name | + + +Type | + + + + + +Description | +
|---|---|---|
platformType |
+
+
+ + + +string + + + + | + + + + + +The string to compare with the platform type |
+
Returns:
@@ -2116,7 +3066,7 @@ the OS called "anything" or the platform called "anything"undefined when the browser is no described in the checkTree
undefined when the browser is no described in the checkTree
undefined when the browser is no described in the checkTree
diff --git a/docs/bowser.js.html b/docs/bowser.js.html index c33671e..eea9571 100644 --- a/docs/bowser.js.html +++ b/docs/bowser.js.html @@ -27,7 +27,7 @@