mobiledetect/mobiledetectlib
Lightweight PHP class to detect mobile phones and tablets using User-Agent plus HTTP headers. Identify device type and specific platforms/brands for responsive content, analytics, or redirects. Widely used and actively maintained via tagged major branches.
Installation:
composer require mobiledetect/mobiledetectlib
Use version ^4.10 for Laravel (PHP 8.2+ compatibility).
Basic Detection:
use Detection\MobileDetect;
$detect = new MobileDetect();
if ($detect->isMobile()) {
// Mobile device logic
}
Laravel Integration:
Bind the detector to the container in AppServiceProvider:
public function register()
{
$this->app->singleton(MobileDetect::class, function () {
return new MobileDetect();
});
}
First Use Case: Redirect mobile users to a mobile-optimized URL:
$detect = app(MobileDetect::class);
if ($detect->isMobile()) {
return redirect()->to('/mobile');
}
isMobile(): Detects phones/tablets.isTablet(): Subset of isMobile() for tablets.is('device_type'): Check for specific devices (e.g., is('iPhone')).features(): Returns an array of detected features (e.g., touch, retina).Create middleware to attach detection results to the request:
namespace App\Http\Middleware;
use Closure;
use Detection\MobileDetect;
class DetectMobileDevice
{
public function handle($request, Closure $next)
{
$detect = new MobileDetect();
$request->merge([
'is_mobile' => $detect->isMobile(),
'device_type' => $detect->getUserAgent(),
'device_features' => $detect->features(),
]);
return $next($request);
}
}
Register in app/Http/Kernel.php:
protected $middleware = [
\App\Http\Middleware\DetectMobileDevice::class,
];
Use Blade directives to render mobile-specific views:
@if(request()->is_mobile)
@include('mobile.layout')
@else
@include('desktop.layout')
@endif
Modify API responses based on device:
public function getData(Request $request)
{
$response = [
'data' => Model::all(),
'meta' => [
'mobile_optimized' => $request->is_mobile,
'features' => $request->device_features,
],
];
return response()->json($response);
}
Leverage Laravel’s cache to avoid redundant detection:
$detect = app(MobileDetect::class);
$cacheKey = 'mobile_detect_' . md5($request->userAgent());
$isMobile = cache()->remember($cacheKey, now()->addHours(1), function () use ($detect) {
return $detect->isMobile();
});
Disable heavy features on mobile:
if (!$request->is_mobile) {
$data['advanced_chart'] = true;
}
Service Provider Binding:
Extend the MobileDetect class and bind it to the container for reusable logic:
$this->app->bind(MobileDetect::class, function () {
$detect = new MobileDetect();
$detect->setUserAgent(request()->userAgent());
return $detect;
});
Request Macros:
Add helper methods to the Request class:
Request::macro('isTablet', function () {
return app(MobileDetect::class)->isTablet();
});
Disable Auto-Initialization: If using custom headers (e.g., CloudFront), disable auto-initialization:
$detect = new MobileDetect(['autoInitOfHttpHeaders' => false]);
$detect->setUserAgent($userAgent);
$detect->setHttpHeaders($headers);
Limit User-Agent Length: Reduce memory usage for long User-Agent strings:
$detect = new MobileDetect(['maximumUserAgentLength' => 300]);
$this->actingAsUser($user)
->withHeaders(['User-Agent' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X)'])
->get('/')
->assertSee('Mobile content');
User-Agent Spoofing:
Sec-CH-UA-Mobile header) for higher accuracy:
$detect->setHttpHeaders([
'Sec-CH-UA-Mobile' => '?1', // Chrome's Client Hints
]);
CloudFront/Proxy Headers:
$detect = new MobileDetect(['autoInitOfHttpHeaders' => false]);
$detect->setHttpHeaders([
'CloudFront-Is-Mobile-Viewer' => 'true',
'CloudFront-Is-Tablet-Viewer' => 'true',
]);
Caching False Positives:
$cacheKey = 'mobile_detect_' . $request->ip() . '_' . $request->session()->getId();
Tablet vs. Mobile Ambiguity:
isTablet() may return false for some tablets (e.g., older Android tablets). Use is('tablet') for broader matching:
if ($detect->is('tablet') || $detect->isTablet()) {
// Tablet logic
}
PHP 8.2+ Strict Types:
Inspect User-Agent:
\Log::debug('User-Agent:', [$detect->getUserAgent()]);
Feature Detection:
features() to debug supported capabilities:
\Log::debug('Device Features:', [$detect->features()]);
Regex Overrides:
$detect->setRegex('my_custom_device', '/MyCustomDevice/i');
if ($detect->is('my_custom_device')) {
// Custom logic
}
Custom Cache Backend:
use Detection\Cache\Cache;
use Psr\SimpleCache\CacheInterface;
$cache = new Cache(app(CacheInterface::class));
$detect = new MobileDetect(['cache' => $cache]);
Subclassing:
MobileDetect for project-specific logic:
class AppMobileDetect extends MobileDetect
{
public function isLegacyMobile()
{
return $this->isMobile() && $this->version('Android') < 5;
}
}
Client Hints Support:
Sec-CH-UA-Mobile header for modern browsers:
$detect->setHttpHeaders([
'Sec-CH-UA-Mobile' => $request->header('Sec-CH-UA-Mobile'),
]);
Configuration:
$detect = new MobileDetect([
'autoInitOfHttpHeaders' => false,
'maximumUserAgentLength' => 400,
'cacheKeyFn' => fn($key) => sha1($key),
]);
Lumen Compatibility:
MobileDetect instance:
$detect = new \Detection\MobileDetect();
$detect->setUserAgent(request()->header('User-Agent'));
Queue Jobs:
// Bad: Cache globally
// $isMobile = cache()->get('mobile_detect');
// Good: Detect per job
$detect = new MobileDetect();
$detect->setUser
How can I help you explore Laravel packages today?