Weave Code
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

Device Detector Laravel Package

piwik/device-detector

Parse User-Agent strings and Browser Client Hints to identify device type (desktop/tablet/mobile/TV/console, etc.), browser/client, operating system, and device brand/model. Universal PHP library from Matomo for accurate device detection.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require matomo/device-detector
    

    Add to composer.json if using Laravel’s autoloader.

  2. First Use Case Parse a User-Agent string in a Laravel controller or middleware:

    use DeviceDetector\DeviceDetector;
    use DeviceDetector\ClientHints;
    
    $userAgent = request()->userAgent();
    $clientHints = ClientHints::factory($_SERVER);
    $dd = new DeviceDetector($userAgent, $clientHints);
    $dd->parse();
    
    // Example: Detect device type
    if ($dd->isMobile()) {
        return response()->json(['device' => 'mobile']);
    }
    
  3. Where to Look First

    • README.md: Quickstart examples and configuration.
    • src/DeviceDetector.php: Core class methods.
    • src/Parser/: Device, OS, and client parsers for granular control.

Implementation Patterns

Core Workflows

  1. Middleware for Device Detection Create a middleware to attach device data to requests:

    namespace App\Http\Middleware;
    
    use Closure;
    use DeviceDetector\DeviceDetector;
    use DeviceDetector\ClientHints;
    
    class DetectDevice
    {
        public function handle($request, Closure $next)
        {
            $dd = new DeviceDetector($request->userAgent(), ClientHints::factory($_SERVER));
            $dd->parse();
            $request->merge([
                'device' => $dd->getDeviceName(),
                'is_mobile' => $dd->isMobile(),
                'client' => $dd->getClient(),
            ]);
            return $next($request);
        }
    }
    

    Register in app/Http/Kernel.php:

    protected $middleware = [
        \App\Http\Middleware\DetectDevice::class,
    ];
    
  2. Service Provider for Caching Configure caching (e.g., Laravel’s cache) in a service provider:

    namespace App\Providers;
    
    use DeviceDetector\DeviceDetector;
    use DeviceDetector\Cache\LaravelCache;
    use Illuminate\Support\ServiceProvider;
    
    class DeviceDetectorServiceProvider extends ServiceProvider
    {
        public function register()
        {
            $this->app->singleton(DeviceDetector::class, function ($app) {
                $dd = new DeviceDetector(request()->userAgent(), ClientHints::factory($_SERVER));
                $dd->setCache(new LaravelCache());
                return $dd;
            });
        }
    }
    
  3. Dynamic Conditional Logic Use detected data in views or controllers:

    // Blade example
    @if(request()->device === 'iPhone')
        <link rel="stylesheet" href="{{ asset('css/ios.css') }}">
    @endif
    

Integration Tips

  • Client Hints: Enable Accept-CH headers in your server (e.g., Nginx) for richer detection:
    add_header Accept-CH "Sec-CH-UA, Sec-CH-UA-Mobile, Sec-CH-UA-Platform";
    
  • Bot Detection: Skip heavy parsing for bots:
    $dd->skipBotDetection(); // Faster but less accurate
    
  • Version Truncation: Adjust for full versions (e.g., 12.3.4 instead of 12.3):
    use DeviceDetector\Parser\Device\AbstractDeviceParser;
    AbstractDeviceParser::setVersionTruncation(AbstractDeviceParser::VERSION_TRUNCATION_NONE);
    

Gotchas and Tips

Pitfalls

  1. Cache Invalidation

    • Laravel’s cache (e.g., LaravelCache) may not invalidate stale entries. Clear cache manually if rules update:
      cache()->forget('device-detector');
      
    • Workaround: Use a short TTL (e.g., 1 hour) or implement a custom cache adapter with versioning.
  2. User-Agent Spoofing

    • Malicious or modified User-Agents may return incorrect results. Validate with:
      if (strpos($userAgent, 'Mozilla/') === false) {
          // Handle suspicious agents
      }
      
  3. Performance Overhead

    • Parsing without caching is slow. Always configure caching:
      $dd->setCache(new LaravelCache()); // Default is memory-only
      
  4. Client Hints Unavailability

    • Not all browsers support Client Hints. Fall back to User-Agent:
      if (!$clientHints->has('Sec-CH-UA')) {
          $dd->parseWithoutClientHints();
      }
      

Debugging

  • Log Raw Data: Inspect parsed results for edge cases:
    \Log::debug('DeviceDetector', [
        'user_agent' => $userAgent,
        'parsed' => $dd->getAll(),
    ]);
    
  • Test with Known Agents: Use User-Agent strings to verify accuracy:
    $dd = new DeviceDetector('Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) ...');
    

Extension Points

  1. Custom Rules Extend parsers by overriding YAML rules (e.g., src/Parser/Device/DeviceParser.php):

    # Add to `device-detector/data/device.yaml`
    Samsung Galaxy S23:
      pattern: Samsung Galaxy S23
      is_tablet: false
    
  2. PSR-6 Cache Adapter For advanced caching, implement DeviceDetector\Cache\CacheInterface:

    class RedisCache implements CacheInterface {
        public function get($key) { /* ... */ }
        public function set($key, $value, $ttl = null) { /* ... */ }
    }
    
  3. Bot Whitelisting Override bot detection logic:

    $dd->setBotParser(new CustomBotParser());
    

Laravel-Specific Tips

  • Store in Session: Cache device data per session:
    session()->put('device', $dd->getAll());
    
  • Eloquent Scopes: Filter models by device:
    public function scopeMobile($query)
    {
        return $query->whereHas('user', fn($q) => $q->where('device', 'like', '%mobile%'));
    }
    
  • API Responses: Attach device data to JSON:
    return response()->json([
        'data' => $model,
        'meta' => [
            'device' => request()->device,
            'is_mobile' => request()->is_mobile,
        ],
    ]);
    
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky