components/modernizr
Modernizr integration for Laravel that adds browser feature detection to your frontend workflow, helping you conditionally load assets and build progressive, cross-browser interfaces with less guesswork.
Treat this as a thin legacy wrapper around Modernizr, not a full asset pipeline. The package has a single 2017 release and very little usage, so first confirm what it actually exposes before designing around it.
composer require components/modernizr
composer show components/modernizr
vendor/components/modernizr:
grep -R "Blade::directive\|class .*ServiceProvider\|function modernizr\|Modernizr::" vendor/components/modernizr/src vendor/components/modernizr/config 2>/dev/null
Most likely you’ll find a service provider plus either a Blade directive, a facade, a helper, or a configurable asset path. Use whichever is documented in the package README, not an assumed API.php artisan vendor:publish --provider="Components\\Modernizr\\ModernizrServiceProvider"
Check the actual provider class name from composer show or the package source if that command fails.config/modernizr.php and any published JS asset. That config usually controls the build file, output path, or enabled feature tests.<html> feature classes for progressive enhancement:
<!doctype html>
<html class="no-js">
<head>
@include('layouts.partials.modernizr')
...
Then conditionally load a polyfill:
if (!Modernizr.promises) {
var s = document.createElement('script');
s.src = '/js/polyfills/promise.min.js';
document.head.appendChild(s);
}
If you are starting a new Laravel application, prefer installing modernizr directly via npm/Vite and adding a small Blade partial. The wrapper adds little value unless you are maintaining a Laravel 5.x-era application where it is already installed.
Keep Modernizr in the document head, synchronously. Modernizr’s main value is adding no-js/feature classes to <html> before CSS and rendering decisions happen. If you load it async or at the end of the body, you get late class application and visible flicker.
{{-- resources/views/layouts/partials/modernizr.blade.php --}}
<script src="{{ asset(config('modernizr.asset', 'vendor/modernizr/modernizr.min.js')) }}"></script>
Use the package’s Blade directive/facade if it provides one; otherwise this partial is the whole integration.
Use a custom Modernizr build, not the full build. Day-to-day, most applications need only a handful of tests: flexbox, cssgrid, promises, fetch, intersectionobserver, picture, srcset, webp, etc. Configure those in your Modernizr build, publish the resulting file, and reference it from config. This keeps the head-blocking payload small.
Pair feature classes with CSS fallbacks. The wrapper’s job ends at loading Modernizr; the real pattern is progressive enhancement:
.no-js .nav { display: block; }
.no-flexbox .grid { display: table; }
if (Modernizr.intersectionobserver) {
initLazyLoading();
} else {
loadLazyLoadingPolyfill().then(initLazyLoading);
}
Use Modernizr.on() for async feature tests. Some tests complete asynchronously. Guard callbacks rather than reading the property immediately:
Modernizr.on('webp', function (result) {
if (result) {
document.documentElement.classList.add('webp');
}
});
Integrate with Laravel’s asset strategy deliberately. This package predates Vite and likely assumes public/vendor or Laravel Mix. For modern apps:
resources/js/vendor/modernizr.js only if Vite can load it in the head before the main bundle.public/vendor/modernizr/ and reference it with asset() plus a version query:
<script src="{{ asset('vendor/modernizr/modernizr.min.js') }}?v={{ config('app.asset_version') }}"></script>
Centralize polyfill loading. Create one small helper instead of scattering script tags:
function loadScript(src) {
return new Promise(function (resolve, reject) {
var s = document.createElement('script');
s.src = src;
s.onload = resolve;
s.onerror = reject;
document.head.appendChild(s);
});
}
var polyfills = [];
if (!Modernizr.fetch) {
polyfills.push(loadScript('/js/polyfills/fetch.min.js'));
}
Promise.all(polyfills).then(function () {
bootApplication();
});
Use config to switch builds by environment. A typical config/modernizr.php pattern:
return [
'asset' => env('MODERNIZR_ASSET', 'vendor/modernizr/modernizr.min.js'),
'enabled' => env('MODERNIZR_ENABLED', true),
];
Then in Blade:
@if (config('modernizr.enabled'))
<script src="{{ asset(config('modernizr.asset')) }}"></script>
@endif
composer.json constraints, service-provider auto-discovery, and whether the provider uses deprecated APIs. If auto-discovery fails, register the provider manually in config/app.php.Modernizr.touch to infer device type, stop and test the actual capability.Modernizr.flexbox but checking Modernizr.flex or Modernizr.cssgrid when the build used a different test name. In the browser console, inspect Object.keys(Modernizr) and confirm the test exists.config/modernizr.php, run:
php artisan config:clear
# or, in production:
php artisan config:cache
A cached config will hide asset-path changes.vendor:publish --force carefully, and document whether the published Modernizr file is generated or hand-maintained.script-src allowances or nonces.<html> element. After page load, you should see classes such as js flexbox cssgrid. If you only see no-js, Modernizr did not execute, the path is wrong, or the script is blocked.public/vendor/modernizr but referencing public/js/modernizr.js.How can I help you explore Laravel packages today?