Device Detection with the User-Agent
Tags: frontend, javascript, ux, webdev
Published: 2021-02-15 19:38:17

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](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) 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

```js
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 example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1peaaglcubuus34cnott.gif)
_Desktop Demo_

![mobile demo example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cddru5ek81yh0s1l6qu4.gif)
_Mobile 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.
<br />
I used this in a federated login

```ts
// 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;
```

```ts
// 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

[Read more from MDN docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent)

<i>Photo by <a href="https://unsplash.com/@danielkorpai?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Daniel Korpai</a> on <a href="https://unsplash.com/s/photos/mobile?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></i>