Device Detection with the User-Agent
Derek Oware
Posted on February 15, 2021
Have you ever wanted to implement a feature for a specific platform or device? Like show a screen or some content to mobile users only or execute a different an action based on the user's device
I usually come across contents on sites that are clearly meant for mobile users only while I browse on desktop.
The User-Agent can be helpful in this scenario.
MDN defines the user agent as
The User-Agent request header is a characteristic string that lets servers and network peers identify the application, operating system, vendor, and/or version of the requesting user agent.
A common format for a user agent string looks like:
Mozilla/5.0 (<system-information>
) <platform>
(<platform-details>
) <extensions>
Detect User's device
To know if a user is on mobile you need to look for "Mobi" in the user agent string as you can see in the example below
const BUTTON = document.querySelector("button");
const { userAgent } = window.navigator;
// Set device to "mobile" if "Mobi" exists in userAgent else set device to "desktop"
const device = userAgent.includes("Mobi") ? "mobile 📱" : "desktop 💻";
BUTTON.addEventListener("click", () => alert(`You are on ${device}`));
The example above result in
Desktop Demo
Test in your browser
To test this in your browser, open the developer tools and click on the 'toggle device' icon. Refresh your page for changes to apply
Practical Example
Here is a practical example of this in my React application.
I used this in a federated login
// Context API for device
import { createContext, useEffect, useState } from "react";
export type TDevice = "mobile" | "desktop";
export const DeviceContext = createContext<TDevice>("mobile");
const DeviceContextProvider: React.FC = ({ children }) => {
const [device, setDevice] = useState<TDevice>("mobile");
useEffect(() => {
const { userAgent } = navigator;
// Set device state
userAgent.includes("Mobi") ? setDevice("mobile") : setDevice("desktop");
}, []);
return (
<DeviceContext.Provider value={device}>{children}</DeviceContext.Provider>
);
};
export default DeviceContextProvider;
// login with provider hook
const useLoginWithProvider = (redirect: (path: string) => void) => {
const device = useContext(DeviceContext);
const [signInAttempt, setSignInAttempt] = useState(false);
const login = async (provider: string) => {
if (device === "mobile") { // Check if user is mobile
firebase.auth().signInWithRedirect(providers[provider]);
setSignInAttempt(true);
} else {
firebase
.auth()
.signInWithPopup(providers[provider])
.then(handleResult)
.catch(error => setError(error.message));
}
};
useEffect(() => {
if (signInAttempt) {
firebase
.auth()
.getRedirectResult()
.then(handleResult)
.catch(error => setError(error.message));
}
}, []);
return login;
};
export default useLoginWithProvider;
Conclusion
Obviously, you can tell this is not meant to replace media queries, however, this can be very useful in your projects. Media Queries are mainly used for responsive pages whereas this method is for device-specific features or content. This is mainly useful when you want your mobile app to behave differently from the desktop version.
You can use this to give mobile users app-like experience especially when dealing with Progressive Web Apps
Photo by Daniel Korpai on Unsplash
Posted on February 15, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.