Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Agent Laravel Package

arcanedev/agent

A lightweight PHP package for detecting the browser, operating system, device type, and bot status behind incoming requests by parsing user-agent strings, with a simple API that fits cleanly into Laravel applications.

View on GitHub
Deep Wiki
Context7

Getting Started

The 9.2.0 release is a low-risk upgrade: it adds PHP 8.0 support and simplifies how the detectors parse input. That makes it a good moment to adopt the package if you are running a modern PHP/Laravel stack, and a safe in-place bump if you are already using it.

  1. Install and confirm the runtime. composer require <vendor>/<package>^9.2 — the package now runs on PHP 8.0+, so check composer.json's php constraint and make sure your CI matrix includes 8.0 if you support it. Run composer why-not <package> 9.2.0 if the resolver balks; it is usually an unrelated dependency holding you back.
  2. Publish config (if offered). php artisan vendor:publish --tag=<package>-config puts the detector definitions and any default thresholds into config/. This is the file to read first — it tells you which detectors ship out of the box and what each returns.
  3. Look at the detector classes before the docs. The src tree is the source of truth for what a detector returns (bool, enum, or a value object). The 9.2.0 "simplified parsing" means some detectors may now return a narrower/cleaner shape than older blog posts describe.
  4. First use case. The canonical day-one scenario is request classification: resolve the detector for the current request, branch on it (mobile vs. desktop, bot vs. human, platform-specific), and use that to choose a view, a redirect, or a feature flag.
// app/Http/Middleware/ClassifyRequest.php
public function handle($request, Closure $next)
{
    $request->attributes->set('client', [
        'is_mobile' => $this->detector->isMobile($request),
        'is_bot'    => $this->detector->isBot($request),
        'platform'  => $this->detector->platform($request),
    ]);

    return $next($request);
}

Implementation Patterns

Resolve from the container, don't call static facades inline. Inject the detector (or the manager) into middleware, controllers, and jobs. This is the difference between a testable integration and one that breaks the moment a user-agent string changes.

Classify once per request, then hang it off the request. Detection is pure function of the request headers, so parse once in middleware and let downstream code read the result. Repeated isMobile() calls across five view composers is the most common performance smell with this kind of package.

Cache the result keyed on the user-agent string, not the user. Detection output depends only on the UA header. Cache::remember('ua:'.sha1($ua), $ttl, fn () => $detector->parse($ua)) gives you a warm cache across users with identical clients.

Use it for presentation and analytics, never for authorization. Detector output is derived from a client-controlled header. Branch on it for responsive layout, asset hints, or "unsupported browser" banners — never for access control or security decisions.

Wrap third-party detectors behind your own interface. If your app calls $detector->platform() in forty places, a future parser change (exactly what 9.2.0 touched) becomes a shotgun refactor. A small ClientContext value object that you populate once insulates the rest of the app.

final class ClientContext
{
    public function __construct(
        public readonly bool $isMobile,
        public readonly bool $isBot,
        public readonly ?string $platform,
    ) {}
}

Blade and API usage. For views, a view composer or Blade::if is cleaner than resolving the detector inside templates. For APIs, serialize the ClientContext into the response envelope so clients can adapt without re-parsing headers themselves.

Test with a user-agent fixture set, not mocks. Because the logic is string parsing, mocking the detector tests nothing. Keep a table of real UA strings (iOS Safari, Android Chrome, curl, Googlebot, an obsolete IE string) and assert the detector's output for each. This is also your early-warning system for parser changes.

Console and queue contexts have no request. Resolving the detector in a job or artisan command will fall back to a default or throw, depending on config. Pass the classified ClientContext into the job rather than re-resolving it.

Gotchas and Tips

9.2.0 simplified detectors' parsing — verify your edge cases. This is the one line in the release notes that can bite. "Simplify" typically means fewer conditional branches and more reliance on a shared parsing pass, which changes results for unusual, legacy, or malformed UA strings. If you have assertions or conditional logic pinned to a specific detector output, add a UA fixture test before upgrading and diff the results after. Treat it as behavior-compatible but not behavior-identical.

PHP 8.0 support usually means a broader constraint, not a narrower one. The new release should not force you off 7.x, but it may pull in dependencies that assume 8.0 semantics. Run the full suite on your lowest supported PHP version, not just the newest.

Config caching will mask detector config edits. php artisan config:cache in deploy is standard, but it means changes to detector definitions in config/ silently do nothing until you re-cache. Add config:clear to local dev scripts.

Bot detection is a spectrum, not a boolean. Crawlers that identify honestly are easy; headless browsers and scrapers with spoofed UAs are not. If you gate anything user-visible on isBot(), pair it with rate limiting and let the detector be a signal rather than a verdict.

Watch for detector output type drift. Simplification passes often normalize return types (e.g., unknown platform returning null instead of 'unknown' or an empty string). Guard with null-safe operators and never rely on truthiness of a string you did not assert.

Extension points to know. Most packages of this shape let you register a custom detector or override the parser via the config's detector array or a service-provider extend hook. If your business logic needs a custom signal (internal tool detection, partner app UAs), add a detector rather than string-matching in a controller — it stays testable and survives parser refactors.

Debugging tip. When a detector returns something surprising, log the raw User-Agent header alongside the parsed output. Nearly every "the detector is wrong" report is actually "the client sent something unusual," and having the UA in the log turns a thirty-minute investigation into a thirty-second one.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings