tattali/mobile-detect-bundle
Symfony bundle that wraps the Mobile Detect library to identify mobile phones, tablets, and desktop browsers from user agents, with service and Twig integration for device-aware routing, views, and responsive experiences.
Architecture fit. The first thing a TPM needs to flag is a framing mismatch: tattali/mobile-detect-bundle is a Symfony bundle, not a Laravel package. It ships a Tattali\MobileDetectBundle extension class, DI service definitions, Symfony Configuration tree, and symfony/* constraints (5.0.x through 8.x). None of that glue is consumable by a Laravel application. What is portable at the PHP level is the underlying engine it wraps — mobiledetect/mobiledetectlib — plus the bundle's opinionated patterns: a configured detector service, a "mobile view" switch, and a redirect listener with hostname/URL rules. In a Laravel context we would be re-implementing roughly 200–400 lines of glue, not integrating a package. That is a meaningful scope correction before any estimate is trusted.
Integration feasibility. Moderate-to-low as a drop-in; moderate as a reference implementation. A Laravel port is mechanical: a service provider binding a singleton detector, a config file mirroring the bundle's redirect/switch_device_view options, and a middleware replacing the bundle's kernel request listener. The risk is not difficulty, it is that we would own a fork of someone else's config semantics with none of the upstream testing. The cleaner alternative — depend directly on mobiledetectlib and write a thin MobileDetector contract plus one middleware — is smaller, fully ours, and avoids inheriting Symfony version cadence entirely. The bundle's real value to us is as a design reference, showing what knobs a redirect strategy needs (device table, host mapping, status code, exclusion paths).
Technical risk.
Sec-CH-UA-Mobile / Sec-CH-UA-Platform client hints as a first-class input, plus navigator.userAgentData client-side as a fallback. Any design that treats UA regex as authoritative will drift in accuracy each browser release.Key questions.
m. subdomains (legacy SEO equity, contractual), or is this inherited technical debt?Stack fit. Poor for Laravel as-shipped, good for Symfony. Recommended Laravel shape:
| Layer | Choice |
|---|---|
| Detector engine | mobiledetect/mobiledetectlib directly |
| Framework glue | First-party Laravel package: service provider + config + middleware |
| Client hints | Read Sec-CH-UA-Mobile / Sec-CH-UA-Platform alongside UA |
| Caching | Cache detection result keyed by hash of UA + hints + Accept |
| Redirect policy | Config-driven, with explicit bypass list and loop guard |
Migration path. Three viable routes, in preference order:
mobiledetectlib call sites. Fastest for a single controller, but scatters detection logic and makes policy changes a grep-and-edit exercise. Acceptable only as a stopgap.Compatibility. mobiledetectlib requires PHP 7.x/8.x and has essentially no framework coupling — this is the durable part of the stack and matches any Laravel 9–12 runtime. The Symfony bundle's constraints are irrelevant to us, which is precisely why we should not vendor it. Also confirm no conflict with an existing jenssegers/agent dependency; running two UA-detection libraries is a source of contradictory answers across the app and should be resolved to one.
Sequencing.
m. subdomain routing.Maintenance. Low code volume, non-trivial ongoing stewardship. The middleware is stable; the detection data is not. Budget for periodic review of misclassification reports after major browser releases, and plan the eventual shift to client hints as primary with UA as fallback. If we own only our thin wrapper, upgrades are a Composer bump on mobiledetectlib. If we fork the bundle, every Symfony-flavored config change becomes a merge decision — an ongoing tax for near-zero benefit in a Laravel app.
Support. A single-maintainer, low-adoption upstream means community support is a GitHub issue queue, not a vendor. Internal ownership must be explicit and named, with an escape hatch: the detector contract should be small enough that swapping the engine (to client hints only, or a different library) is a one-file change. Document the config semantics we adopt — device table, host map, exclusion paths, status code — because those become a de facto product contract with the web team.
Scaling. Detection is CPU-cheap but not free: UA regex batteries run against every request if placed in global middleware. At high request volume this is real overhead on the request path. Mitigations: cache the classification by a hash of UA + client hints + Accept, apply the middleware only to HTML document requests (skip assets, API, health checks), and keep redirects out of the hot path for authenticated/API routes. Caching introduces a second concern below.
Failure modes.
Vary: User-Agent, Sec-CH-UA-Mobile) or desktop and mobile responses will cross-serve. This is the highest-severity failure and is architectural, not code-level.rel=canonical and Vary handling or crawlers will see duplicates.Ramp-up. Fast for the code, slow for the judgment. Any Laravel engineer can wire mobiledetectlib in a day. The learning load is in the policy layer: which routes redirect, which hosts exist, what the bypass list is, how caching varies, and what the rollback story is when mobile users end up somewhere wrong. Assign one owner, keep the config in version control with comments, and require a redirect-policy review for any change to the host map. Net TPM position: treat this package as a reference design worth reading and a Symfony-only runtime option, not a Laravel dependency — and treat the redirect strategy itself as the decision under review, since a responsive-first answer would retire most of this problem entirely.
How can I help you explore Laravel packages today?