Next.jsにはuserAgentを用いて、リクエストからユーザーエージェントを獲得する方法が提供されています。
import { NextResponse, userAgent } from 'next/server';
export function middleware(request: Request) {
const ua = userAgent(request);
console.log(ua);
...
return NextResponse.next();
}
Route Handlerやmiddlewareの引数のrequestをnext/serverが提供するuserAgentで囲むとユーザーエージェントについての情報を取得できます。
取得した値からは7種類の情報を読み取れます。いずれもrequest.headers.get('user-agent')の情報を利用して獲得しています。
1つ目はisBotです。リクエストが既知のBotによるものかを確認します。
Next.jsのバージョン15.1.0の段階では以下のものを検知します。
Googlebot、Mediapartners-Google、AdsBot-Google、googleweblight、Storebot-Google、Google-PageRenderer、Google-InspectionTool、Bingbot、BingPreview、Slurp、DuckDuckBot、baiduspider、yandex、sogou、LinkedInBot、bitlybot、umblr、vkShare、quora link preview、facebookexternalhit、facebookcatalog、Twitterbot、applebot、redditbot、Slackbot、Discordbot、WhatsApp、SkypeUriPreview、ia_archiver
isBotはNext.jsが独自に実装していまが、それ以外の情報はua-parser-jsを用いています。
import { NextResponse, userAgent } from 'next/server';
export function middleware(request: Request) {
const ua = userAgent(request);
// true or false
console.log(ua.isBot);
...
return NextResponse.next();
}
2つ目はuaです。request.headers.get('user-agent')と同じ情報をそのまま渡します。
import { NextResponse, userAgent } from 'next/server';
export function middleware(request: Request) {
const ua = userAgent(request);
// 例: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
console.log(ua.ua);
...
return NextResponse.next();
}
3つ目はbrowserです。オブジェクトでブラウザ名とバージョン、メジャーバージョンを返します。
import { NextResponse, userAgent } from 'next/server';
export function middleware(request: Request) {
const ua = userAgent(request);
// 例: { name: 'Chrome', version: '131.0.0.0', major: '131' }
console.log(ua.browser);
...
return NextResponse.next();
}
4つ目はdeviceです。デバイスの情報をベンダーとモデル、種類に分けて提供します。
ベンダーはAppleとかSonyやGoogle、Teslaなどの情報です。
種類はゲーム機等を意味するconsoleやiPad等を意味するtablet、iPhoneやGalaxyなどを意味するmobile等の情報です。PCに値するものはないようです。
import { NextResponse, userAgent } from 'next/server';
export function middleware(request: Request) {
const ua = userAgent(request);
// 例: { vendor: 'Apple', model: 'Macintosh', type: undefined }
console.log(ua.device);
...
return NextResponse.next();
}
5つ目はengineです。エンジンはレンダリングエンジン名とバージョンを返します。
エンジン名とはWebKitやGeckoなどです。
import { NextResponse, userAgent } from 'next/server';
export function middleware(request: Request) {
const ua = userAgent(request);
// 例: { name: 'Blink', version: '131.0.0.0' }
console.log(ua.engine);
...
return NextResponse.next();
}
6つ目はosです。osの名前を種類を返します。
import { NextResponse, userAgent } from 'next/server';
export function middleware(request: Request) {
const ua = userAgent(request);
// 例: { name: 'Mac OS', version: '10.15.7' }
console.log(ua.os);
...
return NextResponse.next();
}
7つ目はcpuです。CPUのアーキテクチャを返します。architectureだけをキーに持ちます。arm64や Intel x86を使っている場合はia32のように返します。
Apple製品はarm64くらいしか対応していないかも知れません(手元にあるiPhone15・M2チップのMacBook Air・Intel MacBookPro・数年前のiPad Proで試しましたところM2チップのMacBook Airだけ動きました)。
import { NextResponse, userAgent } from 'next/server';
export function middleware(request: Request) {
const ua = userAgent(request);
// 例: { architecture: undefined }
console.log(ua.cpu);
...
return NextResponse.next();
}
以上がuserAgentで確認できることです。内部での依存はありますが、開発に利用するパッケージが他のライブラリに依存することなくユーザーの情報を取得できるのは嬉しいです。
これを用いることで、環境によって異なるサービスを提供することができますが、それは良い行いではありません。できる限り機能をベースに提供する内容を変更しましょう。
詳しくはMDNのユーザーエージェント文字列を用いたブラウザーの判定を読んでください。