【User-Agentは非推奨?】ブラウザ情報の判別をUser-Agent Client Hints(UA-CH)対応にする

# はじめに
アプリ内の共通処理であるブラウザ判定処理を、User-Agent Client Hints に対応させる実装をしました。
今後同じ実装をされる方も多いのではないかと思いますので少しでも参考になればと思い、この記事を書いています。

# User-Agent非推奨の背景
User-Agentは、ユーザーが使用するOSやブラウザの種類、バージョンを判別できる情報です。
HTTPのリクエストヘッダーや、JavaScriptのAPI経由で取得することができます。

JavaScriptのAPIで中身を見てみると、以下のような文字列のデータであることがわかります。
![スクリーンショット 2022-01-12 134225.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1447035/d565eebd-1c89-ed58-ea92-d99fa39e5527.png)
[Google Developers のページ](https://developers-jp.googleblog.com/2021/06/chrome-user-agent.html)によると、段階的にUser-Agentの使用を削減していくとされています。
原因としては、以下のようなものが挙げられます。

- フィンガープリントとして使われる可能性がある
- 構造されていない文字列なので扱いにくい

今のところ、以下の情報はこれからもUser-Agentで取得できるとされています。

- ブラウザのメジャー バージョン
- プラットフォーム名
- デスクトップかモバイルか（またはタブレットか）

しかし、それ以上の深い情報を取ろうとすると、代替手段であるUser Agent Client Hints（以後UA-CH）を使う必要があります。

とはいえ、今回のようなブラウザ情報などのUser-Agentで取れる情報であっても、これからはUA-CH で取得した方がいいことは間違いないと思います。
新しい規格だけあって、構造化されており扱いやすいです。

# User-Agent Client Hints(UA-CH)とは
User-Agentと同様にJavaScript API としても公開され、navigator.userAgentData を利用して取得可能になります。
ブラウザのコンソールで中身を見てみます。

Google Chrome
![chrome.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1447035/8832ddbe-7a5a-9dda-7ee3-8969398d64e4.png)
Microsoft Edge
![edge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1447035/cc141a62-d694-2514-23f9-db4c50b1a540.png)
これで、brands という配列にブラウザ情報は入っていることがわかりました。
[MDNドキュメント](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/userAgentData)を見てみると、現時点で対応しているブラウザは以下の3つです。

- Google Chrome
- Microsoft Edge
- Opera

# ブラウザ判定処理をUA-CH対応で実装してみる
userAgentData がサポートされているブラウザについては userAgentData、それ以外は userAgent で取得するという方針で書いてみました。

```example.js
var userAgentData = window.navigator.userAgentData;
if(userAgentData) {
    // ブラウザがuserAgentData に対応している場合
    var brands = userAgentData.brands;
    for (var i = 0; i < brands.length; i++) {
        var brand = brands[i].brand;
        if (brand.indexOf("Google Chrome") !== -1) {
            // Chrome
            console.log("Chromeです！");
        } else if (brand.indexOf("Microsoft Edge") !== -1) {
            // Edge(EdgeHTML or Chromium)
            console.log("Edge");
        } else if (brand.indexOf("Opera") !== -1) {
            // Opera
            console.log("Operaです！");
        }
    }

} else {
    // ブラウザがuserAgentData に対応していない場合
    var userAgent = window.navigator.userAgent.toLowerCase();
    if (userAgent.indexOf("msie") !== -1 || userAgent.indexOf("trident") !== -1) {
        // IE
        console.log("ieです！");
    } else if (userAgent.indexOf("edge") !== -1) {
        // Edge(EdgeHTML)
        console.log("edgeです！");
    } else if (userAgent.indexOf("edg") !== -1) {
        // Edge(Chromium)
        console.log("edgeです！");
    } else if (userAgent.indexOf("chrome") !== -1) {
        // Chrome
        console.log("chromeです！");
    } else if (userAgent.indexOf("safari") !== -1) {
        // Safari
        console.log("safariです！");
    } else if (userAgent.indexOf("firefox") !== -1) {
        // FireFox
        console.log("fireboxです！");
    } else if (userAgent.indexOf("opera") !== -1) {
        // Opera
        console.log("operaです！");
    }
};
```

# おわりに
Chromiumの動向に注視していきたいと思います。
# 参照
[Google Developers公式サイト](https://developers-jp.googleblog.com/2021/06/chrome-user-agent.html)
[Chromium公式サイト](https://www.chromium.org/updates/ua-reduction)
[MDNドキュメント](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/userAgentData)