atldays / laravel-agent
Laravel package for parsing user-agent strings into typed browser, operating system, device, and bot objects.
Requires
- php: ^8.2
- atldays/laravel-url: ^1.0
- illuminate/contracts: ^11.0|^12.0|^13.0
- illuminate/database: ^11.0|^12.0|^13.0
- illuminate/http: ^11.0|^12.0|^13.0
- illuminate/support: ^11.0|^12.0|^13.0
- matomo/device-detector: ^6.5
- spatie/laravel-data: ^4.0
Requires (Dev)
- laravel/pint: ^1.18
- orchestra/testbench: ^9.0|^10.0|^11.0
- phpunit/phpunit: ^11.5|^12.5
This package is auto-updated.
Last update: 2026-04-20 14:42:57 UTC
README
atldays/laravel-agent is a Laravel package for parsing user-agent strings into clean, typed objects.
It gives you a comfortable Laravel-first API for working with:
- browsers
- operating systems
- devices
- bots
- request user-agent strings
Under the hood, the package uses matomo/device-detector, while exposing a clean developer experience through Laravel service container bindings, a request macro, facades, model helpers, and typed DTOs powered by spatie/laravel-data.
Features
- Laravel auto-discovery support
request()->agent()request macroAgentfacade for the current request agentAgentManagerfacade for on-demand detection- dependency injection support via
AgentContract - container binding for
AgentContract - typed DTO objects for browser, OS, device, bot, and producer data
- Eloquent cast for persisted user-agent strings
- model trait for convenient access to parsed agents
- bot-blocking middleware alias
- test coverage for real user-agent fixtures and framework integration
Requirements
- PHP
^8.2 - Laravel
^11.0|^12.0|^13.0
Installation
composer require atldays/laravel-agent
The package supports Laravel package auto-discovery, so no manual provider registration is required.
Quick Start
Request macro
use Illuminate\Http\Request; Route::get('/', function (Request $request) { $agent = $request->agent(); return [ 'user_agent' => $agent->userAgent(), 'hash' => $agent->hash(), 'browser' => $agent->browser()?->name(), 'os' => $agent->os()?->name(), 'device' => $agent->device()?->device(), 'is_bot' => $agent->isBot(), ]; });
Facades
use Atldays\Agent\Facades\Agent; use Atldays\Agent\Facades\AgentManager; $currentAgent = AgentManager::request(); $customAgent = AgentManager::detect($userAgent); $browser = Agent::browser(); $os = Agent::os(); $device = Agent::device(); $bot = Agent::bot();
Dependency injection
use Atldays\Agent\Contracts\AgentContract; class SomeAction { public function __invoke(AgentContract $agent): array { return [ 'browser' => $agent->browser()?->name(), 'device' => $agent->device()?->device(), 'is_bot' => $agent->isBot(), ]; } }
Core API
The main parsed object is Atldays\Agent\Contracts\AgentContract.
Available methods:
userAgent(): stringhash(): stringbrowser(): ?BrowserContractos(): ?OsContractdevice(): ?DeviceContractbot(): ?BotContractisBot(): booltoArray(): array
Example:
$agent = request()->agent(); if ($agent->isBot()) { // ... } $browser = $agent->browser(); $os = $agent->os(); $device = $agent->device();
DTO Objects
The package returns typed DTO objects instead of raw arrays.
Browser DTO
Returned by:
$agent->browser()
Class:
Atldays\Agent\Data\Browser
Available data methods:
name(): stringshortName(): ?stringversion(): ?stringfamily(): ?stringengine(): ?stringengineVersion(): ?string
Available helper methods:
isChrome(): boolisEdge(): boolisFirefox(): boolisOpera(): boolisSafari(): bool
Example:
$browser = request()->agent()->browser(); if ($browser?->isEdge()) { // ... }
OS DTO
Returned by:
$agent->os()
Class:
Atldays\Agent\Data\Os
Available data methods:
name(): stringshortName(): ?stringversion(): ?stringfamily(): ?stringplatform(): ?string
Available helper methods:
isApple(): boolisAndroid(): boolisIos(): boolisLinux(): boolisMacOs(): boolisWindows(): bool
Example:
$os = request()->agent()->os(); if ($os?->isLinux()) { // ... }
Device DTO
Returned by:
$agent->device()
Class:
Atldays\Agent\Data\Device
Available data methods:
type(): DeviceTypedevice(): stringbrand(): ?stringmodel(): ?string
Available helper methods:
isDesktop(): boolisMobile(): boolisTablet(): boolisPhone(): boolisApple(): boolisIphone(): bool
Example:
$device = request()->agent()->device(); if ($device?->isTablet()) { // ... }
Bot DTO
Returned by:
$agent->bot()
Class:
Atldays\Agent\Data\Bot
Available data methods:
name(): stringcategory(): ?stringurl(): ?\Atldays\Url\Contracts\Urlproducer(): ?ProducerContract
Producer DTO
Returned by:
$agent->bot()?->producer()
Class:
Atldays\Agent\Data\Producer
Available data methods:
name(): ?stringurl(): ?\Atldays\Url\Contracts\Url
Manual Detection
If you already have a user-agent string, you can parse it directly:
use Atldays\Agent\Facades\AgentManager; $agent = AgentManager::detect($userAgent); $browserName = $agent->browser()?->name(); $isAndroid = $agent->os()?->isAndroid(); $isMobile = $agent->device()?->isMobile();
You can also resolve the manager directly:
use Atldays\Agent\AgentManager; $manager = app(AgentManager::class); $agent = $manager->detect($userAgent);
Eloquent Integration
Agent cast
Use AgentCast when your model stores a raw user_agent string but you want to work with an AgentContract.
use Atldays\Agent\Casts\AgentCast; use Illuminate\Database\Eloquent\Model; class Visit extends Model { protected function casts(): array { return [ 'user_agent' => AgentCast::class, ]; } }
Now the attribute will resolve to an AgentContract:
$visit->user_agent->browser()?->name(); $visit->user_agent->device()?->isMobile();
HasAgent trait
Use the trait when you want a dedicated agent() helper on your model.
use Atldays\Agent\Concerns\HasAgent; use Illuminate\Database\Eloquent\Model; class Visit extends Model { use HasAgent; }
Example:
$visit->agent()->browser()?->name(); $visit->agent()->os()?->isMacOs(); $visit->agent()->device()?->isPhone();
By default the trait reads from the user_agent column. You can override that:
protected function getUserAgentColumn(): string { return 'agent_string'; }
Middleware
The package registers the agent.block-bots middleware alias.
Block all bots
Route::middleware('agent.block-bots')->group(function () { // ... });
Allow selected bots
Route::middleware('agent.block-bots:Googlebot,Bingbot')->group(function () { // ... });
If a request is detected as a bot and is not allow-listed, the middleware throws a 403 Forbidden response.
Testing
Run the test suite:
composer test
Run formatting:
composer format composer format:test
Run both:
composer check
Why Laravel Agent
Most user-agent packages stop at “parse a string into an array”.
laravel-agent is built to feel native inside a Laravel application:
- typed objects instead of loose arrays
- request-first API for day-to-day usage
- model integration for persisted user agents
- framework-friendly container bindings and facade support
- focused helper methods on DTOs for browser, OS, and device checks
License
The MIT License (MIT). Please see LICENSE.md for more information.