Detect Device & Browser of Visitors to Your Website

Published: January 9, 2024

Detect Device & Browser of Visitors to Your Website

When operating a website like the one you are visiting (www.danyelkoca.com) it is crucial to get insights about people visiting your site.

You can't improve what you don't measure.

Peter Drucker

One important insight about your users is the device and browser they are using while they are visiting your site.

Why? This information can help you improve your site by examplary actions below:

  1. Gain insights about most commonly used device&browser and optimize your site accordingly
  2. Deprioritize actions that only benefit a minority device & browser (E.g., Tablet device, Opera browser)
  3. Identify patterns specific to certain devices & browsers (E.g. certain function not being used on Safari)

Now let's deep-dive into the code!

1. Device Detection

In order to identify the device, we use the window.navigator.userAgent function in JavaScript. This function returns a string as below:

console.log(window.navigator.userAgent);
// >> Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36

The result is what I see on my computer, which is a MacBook Pro used with Chrome Browser.

Let's analyze the output:

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36

We see that this function not only outputs the device

Macintosh; Intel Mac OS X 10_15_7

but also returns a bunch of other information like

Mozilla/5.0, AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36

For now, we focus on the part of the output that signifies the device

Macintosh; Intel Mac OS X 10_15_7

It gets it right that Im accessing this website through a MacBook, however there is no information about the model of this MacBook (E.g. Air, Pro)

Moreover it gets multiple things wrong. My MacBook is not Intel chip (it is M1) and it is not using OSX 10.15.7.

So, when using this function to determine the device, only infer the device, as model of the device and OS running on the device can be misleading.

Using the userAgent string, we can write a regex in order to classify the user's device as mobile or desktop, based on this StackOverflow answer.

let userAgentString = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
	
function deviceDetection(userAgentString) {
	let device = 'Desktop';

	if (
		/(android|bbd+|meego).+mobile|avantgo|bada/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)/|plucker|pocket|psp|series(4|6)0|symbian|treo|up.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(
			userAgentString
		)
	) {
		device = 'Mobile';
	}

	return device;
}

console.log(browserDetection(userAgentString));
// >> Desktop

2. Browser Detection

Now let's focus on the part of the output that signifies the browser

Mozilla/5.0, AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36

Browser detection thorugh userAgent is notoriously convoluted as this output itself includes 3 browsers:

  1. Mozilla/5.0 (Firefox?)
  2. Chrome/120.0.0.0
  3. Safari/537.36

According to MDN Web Docs below table can be used to infer about the browser using UserAgent string:

Engine Must contain Must not contain
Firefox Firefox/xyz Seamonkey/xyz
Seamonkey Seamonkey/xyz
Chrome Chrome/xyz Chromium/xyz or Edg.*/xyz
Chromium Chromium/xyz
Safari Safari/xyz Chromium/xyz or Edg.*/xyz
Opera 15+ (Blink-based engine) OPR/xyz
Opera 15+ (Presto-based engine) Opera/xyz

So let's write a regex to definethe browser based on the conditions provided by MDN.

let userAgentString = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';

function browserDetection(userAgentString) {
	let browser = 'unknown';

	if (/Firefox/.*/.test(userAgentString) && !/Seamonkey/.*/.test(userAgentString))
		browser = 'Firefox';
	else if (/Seamonkey/.*/.test(userAgentString)) browser = 'Seamonkey';
	else if (
		/Chrome/.*/.test(userAgentString) &&
		!/Chromium/.*/.test(userAgentString) &&
		!/Edg.*/.*/.test(userAgentString)
	)
		browser = 'Chrome';
	else if (/Chromium/.*/.test(userAgentString)) browser = 'Chromium';
	else if (
		/Safari/.*/.test(userAgentString) &&
		!/Chromium/.*/.test(userAgentString) &&
		!/Edg.*/.*/.test(userAgentString)
	)
		browser = 'Safari';
	else if (/OPR/.*/.test(userAgentString)) browser = 'Opera 15+ (Blink-based engine)';
	else if (/Opera/.*/.test(userAgentString)) browser = 'Opera 15+ (Presto-based engine)';

	return browser;
}

console.log(browserDetection(userAgentString));
// >> Chrome

We have succesfully classified my browser, which was indeed Chrome. However, the attentive eyes will realize that my userAgent string also satisfied Safari's conditions. Since Chrome condition is tested before Safari; the browser is classified as Chrome, but further testing is needed whether testing for Chrome before Safari always yields the expected results.

3. Conclusion

By using above 2 functions - deviceDetection, browserDetection - you can now succesfully classify the device and the broser of your users. Note that window.navigator.userAgent is compatible with all modern browsers, so you can safely use it. Any questions, feel free to let me in below comment section.

Happy hacking!

Leave comment

Comments

Check out other blog posts

Create A Simple and Dynamic Tooltip With Svelte and JavaScript

2024/06/19

Create A Simple and Dynamic Tooltip With Svelte and JavaScript

JavaScriptSvelteSimpleDynamicTooltipFront-end
Create an Interactive Map of Tokyo with JavaScript

2024/06/17

Create an Interactive Map of Tokyo with JavaScript

SvelteSVGJavaScriptTailwindInteractive MapTokyoJapanTokyo Metropolitan Area23 Wards
How to Easily Fix Japanese Character Issue in Matplotlib

2024/06/14

How to Easily Fix Japanese Character Issue in Matplotlib

MatplotlibGraphChartPythonJapanese charactersIssueBug
Book Review | Talking to Strangers: What We Should Know about the People We Don't Know by Malcolm Gladwell

2024/06/13

Book Review | Talking to Strangers: What We Should Know about the People We Don't Know by Malcolm Gladwell

Book ReviewTalking to StrangersWhat We Should Know about the People We Don't KnowMalcolm Gladwell
Most Commonly Used 3,000 Kanjis in Japanese

2024/06/07

Most Commonly Used 3,000 Kanjis in Japanese

Most CommonKanji3000ListUsage FrequencyJapaneseJLPTLanguageStudyingWordsKanji ImportanceWord Prevalence
Replace With Regex Using VSCode

2024/06/07

Replace With Regex Using VSCode

VSCodeRegexFindReplaceConditional Replace
Do Not Use Readable Store in Svelte

2024/06/06

Do Not Use Readable Store in Svelte

SvelteReadableWritableState ManagementStoreSpeedMemoryFile Size
Increase Website Load Speed by Compressing Data with Gzip and Pako

2024/06/05

Increase Website Load Speed by Compressing Data with Gzip and Pako

GzipCompressionPakoWebsite Load SpeedSvelteKit
Find the Word the Mouse is Pointing to on a Webpage with JavaScript

2024/05/31

Find the Word the Mouse is Pointing to on a Webpage with JavaScript

JavascriptMousePointerHoverWeb Development
Create an Interactive Map with Svelte using SVG

2024/05/29

Create an Interactive Map with Svelte using SVG

SvelteSVGInteractive MapFront-end
Book Review | Originals: How Non-Conformists Move the World by Adam Grant & Sheryl Sandberg

2024/05/28

Book Review | Originals: How Non-Conformists Move the World by Adam Grant & Sheryl Sandberg

Book ReviewOriginalsAdam Grant & Sheryl SandbergHow Non-Conformists Move the World
How to Algorithmically Solve Sudoku Using Javascript

2024/05/27

How to Algorithmically Solve Sudoku Using Javascript

Solve SudokuAlgorithmJavaScriptProgramming
How I Increased Traffic to my Website by 10x in a Month

2024/05/26

How I Increased Traffic to my Website by 10x in a Month

Increase Website TrafficClicksImpressionsGoogle Search Console
Life is Like Cycling

2024/05/24

Life is Like Cycling

CyclingLifePhilosophySuccess
Generate a Complete Sudoku Grid with Backtracking Algorithm in JavaScript

2024/05/19

Generate a Complete Sudoku Grid with Backtracking Algorithm in JavaScript

SudokuComplete GridBacktracking AlgorithmJavaScript
Why Tailwind is Amazing and How It Makes Web Dev a Breeze

2024/05/16

Why Tailwind is Amazing and How It Makes Web Dev a Breeze

TailwindAmazingFront-endWeb Development
Generate Sitemap Automatically with Git Hooks Using Python

2024/05/15

Generate Sitemap Automatically with Git Hooks Using Python

Git HooksPythonSitemapSvelteKit
Book Review | Range: Why Generalists Triumph in a Specialized World by David Epstein

2024/05/14

Book Review | Range: Why Generalists Triumph in a Specialized World by David Epstein

Book ReviewRangeDavid EpsteinWhy Generalists Triumph in a Specialized World
What is Svelte and SvelteKit?

2024/05/13

What is Svelte and SvelteKit?

SvelteSvelteKitFront-endVite
Internationalization with SvelteKit (Multiple Language Support)

2024/05/12

Internationalization with SvelteKit (Multiple Language Support)

InternationalizationI18NSvelteKitLanguage Support
Reduce Svelte Deploy Time With Caching

2024/05/11

Reduce Svelte Deploy Time With Caching

SvelteEnhanced ImageCachingDeploy Time
Lazy Load Content With Svelte and Intersection Oberver

2024/05/10

Lazy Load Content With Svelte and Intersection Oberver

Lazy LoadingWebsite Speed OptimizationSvelteIntersection Observer
Find the Optimal Stock Portfolio with a Genetic Algorithm

2024/05/10

Find the Optimal Stock Portfolio with a Genetic Algorithm

Stock marketPortfolio OptimizationGenetic AlgorithmPython
Convert ShapeFile To SVG With Python

2024/05/09

Convert ShapeFile To SVG With Python

ShapeFileSVGPythonGeoJSON
Reactivity In Svelte: Variables, Binding, and Key Function

2024/05/08

Reactivity In Svelte: Variables, Binding, and Key Function

SvelteReactivityBindingKey Function
Book Review | The Art Of War by Sun Tzu

2024/05/07

Book Review | The Art Of War by Sun Tzu

Book ReviewThe Art Of WarSun TzuThomas Cleary
Specialists Are Dead. Long Live Generalists!

2024/05/06

Specialists Are Dead. Long Live Generalists!

SpecialistGeneralistParadigm ShiftSoftware Engineering
Analyze Voter Behavior in Turkish Elections with Python

2024/05/03

Analyze Voter Behavior in Turkish Elections with Python

TurkeyAge Analysis2018 ElectionsVoter Behavior
Create Turkish Voter Profile Database With Web Scraping

2024/05/01

Create Turkish Voter Profile Database With Web Scraping

PythonSeleniumWeb ScrapingTurkish Elections
Make Infinite Scroll With Svelte and Tailwind

2024/04/30

Make Infinite Scroll With Svelte and Tailwind

SvelteTailwindInfinite ScrollFront-end
How I Reached Japanese Proficiency In Under A Year

2024/04/29

How I Reached Japanese Proficiency In Under A Year

JapaneseProficiencyJLPTBusiness
Use-ready Website Template With Svelte and Tailwind

2024/04/25

Use-ready Website Template With Svelte and Tailwind

Website TemplateFront-endSvelteTailwind
Lazy Engineers Make Lousy Products

2024/01/29

Lazy Engineers Make Lousy Products

Lazy engineerLousy productStarbucksSBI
On Greatness

2024/01/28

On Greatness

GreatnessMeaning of lifeSatisfactory lifePurpose
Converting PDF to PNG on a MacBook

2024/01/28

Converting PDF to PNG on a MacBook

PDFPNGMacBookAutomator
Recapping 2023: Compilation of 24 books read

2023/12/31

Recapping 2023: Compilation of 24 books read

BooksReading2023Reflections
Create a Photo Collage with Python PIL

2023/12/30

Create a Photo Collage with Python PIL

PythonPILImage ProcessingCollage
Anatomy of a ChatGPT Response

2024/01/19

Anatomy of a ChatGPT Response

ChatGPTLarge Language ModelMachine LearningGenerative AI