crossknowledge/devicedetect-bundle
composer require crossknowledge/devicedetect-bundle
config/bundles.php:
CrossKnowledge\DeviceDetectBundle\CrossKnowledgeDeviceDetectBundle::class => ['all' => true],
config/packages/crossknowledge_device_detect.yaml:
cross_knowledge_device_detect:
user_agent: '%kernel.request%'
use CrossKnowledge\DeviceDetectBundle\DeviceDetector;
public function index(DeviceDetector $detector)
{
$device = $detector->detect();
return new Response('Detected: ' . $device->getClient('type'));
}
DeviceDetector: Main service for detection.Device: Holds parsed device data (OS, browser, etc.).ClientHint: For handling HTTP headers like Sec-CH-UA.Inject DeviceDetector into controllers/services to parse the current request’s User-Agent:
public function show(DeviceDetector $detector, Request $request)
{
$device = $detector->detect($request->headers->get('User-Agent'));
$isMobile = $device->getClient('type') === 'mobile';
}
Cache detection results to avoid reprocessing the same User-Agent:
$cacheKey = 'device_' . md5($userAgent);
$device = $cache->get($cacheKey) ?? $detector->detect($userAgent);
$cache->set($cacheKey, $device, 3600); // Cache for 1 hour
Use detected data to modify responses (e.g., redirect mobile users to a different URL):
if ($device->getClient('type') === 'mobile') {
return redirect()->to('/mobile');
}
Leverage Sec-CH-UA headers for more accurate detection:
$clientHints = $request->headers->get('Sec-CH-UA');
$device = $detector->detect($userAgent, $clientHints);
Trigger actions based on device detection (e.g., logging or analytics):
// src/EventListener/DeviceListener.php
public function onKernelRequest(GetResponseEvent $event)
{
$device = $detector->detect($event->getRequest());
// Log or track device data
}
Register in services.yaml:
services:
App\EventListener\DeviceListener:
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
Pass the DeviceDetector to Twig templates:
# config/packages/twig.yaml
twig:
globals:
device_detector: '@cross_knowledge_device_detect.device_detector'
Use in templates:
{% if device_detector.detect(app.request).getClient('type') == 'mobile' %}
<link rel="stylesheet" href="{{ asset('css/mobile.css') }}">
{% endif %}
Include device data in API responses for analytics:
return $this->json([
'data' => $data,
'device' => [
'type' => $device->getClient('type'),
'os' => $device->getOs('name'),
'browser' => $device->getClient('name'),
],
]);
Mock the DeviceDetector in tests:
$mockDetector = $this->createMock(DeviceDetector::class);
$mockDetector->method('detect')->willReturn($mockDevice);
$this->container->set(DeviceDetector::class, $mockDetector);
matomo/device-detector (last updated 2021), which may not include modern devices/browsers.DeviceDetector rules or fork the package.User-Agent strings can be slow for high-traffic sites.mobiledetectlib.Sec-CH-UA headers are only supported in Chrome/Edge (since ~2021).User-Agent if Sec-CH-UA is missing.$device->getClient('user_agent') to inspect raw input.Dump the full device object to debug:
$device = $detector->detect($request->headers->get('User-Agent'));
dump($device->getAll());
Output includes:
client: Browser/device info.os: Operating system.bot: Bot detection.If detection is inaccurate, update the rules in:
$detector->getParser()->setRules([/* custom rules */]);
(See matomo/device-detector for rule formats.)
Log problematic User-Agent strings for analysis:
if ($device->getClient('type') === 'unknown') {
\Log::warning('Unknown device: ' . $userAgent);
}
Extend detection logic by subclassing DeviceDetector:
class CustomDeviceDetector extends DeviceDetector
{
protected function getCustomRules()
{
return [
'custom_device' => '/CustomDevice\/1\.0/',
];
}
}
Register as a service:
services:
App\Service\CustomDeviceDetector:
decorates: 'cross_knowledge_device_detect.device_detector'
arguments: ['@App\Service\CustomDeviceDetector.inner']
Attach custom metadata to the Device object:
$device->setCustom('is_enterprise', true);
Replace the default detector entirely:
services:
cross_knowledge_device_detect.device_detector:
class: App\Service\MyCustomDetector
arguments: ['@service_container']
By default, the bundle uses Symfony’s RequestStack. To use a custom source:
cross_knowledge_device_detect:
user_agent: 'app.request_stack' # Default
# OR
user_agent: '@custom.request_provider'
Skip parsing entirely (e.g., for performance):
cross_knowledge_device_detect:
enabled: false
Then manually instantiate DeviceDetector without auto-configuration.
The underlying matomo/device-detector supports multiple languages. Configure in PHP:
$detector->getParser()->setLanguage('en'); // Default
How can I help you explore Laravel packages today?