nette/assets
Nette Assets provides a lightweight way to manage web assets in Nette apps. It helps register, version, and generate URLs for CSS/JS and other files, supporting cache busting and clean asset linking in templates and presenters.
Install the Package:
composer require nette/assets
Register AssetManager in Laravel’s Service Provider:
use Nette\Assets\AssetManager;
public function register()
{
$this->app->singleton('asset.manager', function ($app) {
$manager = new AssetManager();
$manager->setBasePath($app->publicPath());
$manager->addDirectory($app->publicPath('assets/css'));
$manager->addDirectory($app->publicPath('assets/js'));
return $manager;
});
}
First Use Case: Generate Asset URLs in Controllers/Views
// In a controller
public function index()
{
$cssUrl = app('asset.manager')->getUrl('main.css');
return view('home', compact('cssUrl'));
}
<!-- In Blade template -->
<link rel="stylesheet" href="{{ $cssUrl }}">
Font Asset with Crossorigin Support:
$font = new \Nette\Assets\FontAsset('fonts/roboto.woff2');
$font->setCrossorigin('anonymous');
$fontUrl = $font->getUrl();
AssetManager: Core class for registering directories and generating URLs.addDirectory(): Method to define asset roots (e.g., public_path('assets')).getUrl(): Resolves paths with optional versioning.FontAsset: Specialized class for font assets with crossorigin support.setVersion(): Enable cache-busting for production.Bind AssetManager as a singleton in AppServiceProvider:
public function register()
{
$this->app->singleton('asset.manager', function ($app) {
$manager = new AssetManager();
$manager->setBasePath($app->publicPath());
$manager->addDirectory($app->publicPath('assets/css'));
$manager->addDirectory($app->publicPath('assets/js'));
$manager->setVersion(config('app.version')); // Optional: Append version query
return $manager;
});
}
Create a custom Blade directive:
// app/Providers/BladeServiceProvider.php
use Illuminate\Support\Facades\Blade;
public function boot()
{
Blade::directive('asset', function ($expression) {
return "<?php echo app('asset.manager')->getUrl({$expression}); ?>";
});
}
Usage in Blade:
<link rel="stylesheet" href="@asset('main.css')">
Load assets conditionally based on routes or user roles:
public function index()
{
$assets = app('asset.manager');
$cssFiles = ['main.css'];
if (auth()->check()) {
$cssFiles[] = 'auth.css';
}
return view('home', ['cssUrls' => $assets->getUrlList($cssFiles)]);
}
$manager->setVersion('1.0'); // Outputs: /css/main.css?v=1.0
if (!app()->isLocal()) {
$manager->setVersion(config('app.version'));
}
$manager->getUrl("main.css?v=" . filemtime(public_path('assets/css/main.css')));
Leverage FontAsset for secure font loading:
// In a controller or service
$font = new \Nette\Assets\FontAsset('fonts/roboto.woff2');
$font->setCrossorigin('anonymous');
$fontUrl = $font->getUrl();
Blade Example:
<link rel="preload" href="{{ $assets->getFontUrl('roboto.woff2', 'anonymous') }}" as="font" crossorigin="anonymous">
Use ViteMapper for Vite dev server proxying:
$manager = new AssetManager();
$manager->setMapper(new \Nette\Assets\ViteMapper('http://localhost:5173'));
$manager->addDirectory(public_path('resources/js'));
Blade Usage:
<script src="@asset('app.js')"></script>
Organize assets by context (e.g., admin, frontend):
$manager->addDirectory(public_path('assets/admin/css'), 'admin');
$manager->addDirectory(public_path('assets/frontend/js'), 'frontend');
Usage:
$adminCss = $manager->getUrl('styles.css', 'admin');
Add nonce attributes for security:
$manager->setNonce('abc123');
$jsUrl = $manager->getUrl('script.js'); // Outputs: script.js?nonce=abc123
Blade Usage:
<script src="{{ $jsUrl }}" nonce="{{ $manager->getNonce() }}"></script>
getUrl() resolves from registered directories, not the current working directory.
// ❌ Fails if 'assets' isn’t registered
$manager->getUrl('../assets/main.css');
// ✅ Correct
$manager->addDirectory(public_path('assets'));
$manager->getUrl('main.css');
Main.css vs. main.css) breaks lookups on Linux.setVersion() isn’t used, manually append hashes:
$version = md5_file(public_path('assets/css/main.css'));
$manager->getUrl("main.css?v=$version");
development to avoid broken asset links:
if (!app()->environment('local')) {
$manager->setVersion(config('app.version'));
}
crossorigin:
$font = new FontAsset('https://cdn.example.com/fonts/roboto.woff2');
$font->setCrossorigin('anonymous'); // ❌ Forgotten → Font blocks loading
nette/assets for path resolution only; let Laravel Mix/Vite handle bundling.public/build/.$manager->addDirectory(public_path('build'));
$manager->setVersion(config('app.version'));
dd($manager->getDirectories()); // Verify paths
$manager->getFullPath('main.css'); // Debug physical location
$font = new FontAsset('fonts/roboto.woff2');
dd($font->getUrl(), $font->getCrossorigin());
@foreach($assets->getFontUrls(['roboto.woff2']) as $url)
<link rel="preload" href="{{ $url }}" as="font" crossorigin="anonymous">
@endforeach
<script src="{{ $assets->getUrl('analytics.js') }}" defer></script>
Nette\Assets\IStorage for S3/Azure:
class S3Storage implements IStorage {
public function url($path) { /* ... */ }
public function exists($path) { /* ... */ }
}
$manager->setStorage(new S3Storage());
FontAsset:
class SecureFontAsset extends FontAsset {
public function __construct($path) {
parent::__construct($path);
$this->setCrossorigin('anonymous');
}
}
AssetManagerHow can I help you explore Laravel packages today?