symfony/asset
Symfony Asset component helps generate and version URLs for web assets like CSS, JavaScript, and images. Supports cache busting via version strategies and base paths/URLs, making it easy to reference assets consistently across environments and CDNs.
symfony/asset in a Laravel project. Laravel’s native tools (asset(), Vite, Mix) already handle asset management efficiently.href="/css/app.css") with Laravel’s asset() helper:
// Blade template
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
// PHP
echo asset('js/app.js');
@vite() Blade directives for compiled assets:
@vite(['resources/css/app.css', 'resources/js/app.js'])
app.css?id=abc123). No manual versioning required.Use Laravel’s asset() helper for all static file references:
// routes/web.php
Route::get('/styles', function () {
return asset('css/styles.css'); // Returns full URL (e.g., /storage/css/styles.css)
});
Blade Example:
<img src="{{ asset('images/logo.png') }}" alt="Logo">
Replace Mix with Vite for modern asset pipelines:
npm install vite @vitejs/plugin-laravel
Vite Config (vite.config.js):
import laravel from 'laravel-vite-plugin';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.js'],
refresh: true,
}),
],
});
Blade Integration:
@vite(['resources/css/app.css', 'resources/js/app.js'])
Use Laravel’s mix() helper (if using Mix) or Vite’s dynamic imports:
<!-- Mix (deprecated but still used in some projects) -->
<script src="{{ mix('js/app.js') }}"></script>
<!-- Vite -->
<script type="module" src="{{ vite('resources/js/app.js') }}"></script>
Leverage Laravel’s config('app.asset_path') or environment variables:
// config/app.php
'asset_path' => env('ASSET_PATH', 'storage'),
// In Blade
<link href="{{ config('app.asset_path') }}/css/app.css" rel="stylesheet">
Use Laravel’s asset() with a CDN URL or environment-specific base paths:
// config/app.php
'asset_url' => env('ASSET_URL', null),
// Helper function (add to `app/Helpers.php`)
function cdn_asset($path) {
return config('app.asset_url') ? config('app.asset_url') . $path : asset($path);
}
Usage:
<script src="{{ cdn_asset('js/vendor.js') }}"></script>
If you must use symfony/asset in a Laravel project (e.g., legacy Symfony module), follow these steps:
composer require symfony/asset
Note: Expect dependency conflicts with Laravel’s illuminate packages. Use replace in composer.json to avoid pulling in Symfony’s full stack:
"replace": {
"symfony/http-foundation": "*",
"symfony/options-resolver": "*"
}
Register the AssetMapper in Laravel’s service container:
// app/Providers/AppServiceProvider.php
use Symfony\Component\Asset\Packages;
use Symfony\Component\Asset\PathPackage;
use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy;
public function register()
{
$this->app->singleton('asset.mapper', function () {
$packages = new Packages();
$packages->addPackage(new PathPackage());
return new \Symfony\Component\Asset\AssetMapper(
$packages,
new EmptyVersionStrategy()
);
});
}
Create a facade or helper to bridge Symfony’s AssetMapper with Laravel:
// app/Helpers/SymfonyAsset.php
use Symfony\Component\Asset\AssetMapper;
function symfony_asset(string $path): string
{
return app(AssetMapper::class)->getUrl($path);
}
Usage:
<link href="{{ symfony_asset('css/symfony-module.css') }}" rel="stylesheet">
For cache busting, configure a VersionStrategy (e.g., JsonManifestVersionStrategy for Vite/Mix manifests):
// In AppServiceProvider
use Symfony\Component\Asset\VersionStrategy\JsonManifestVersionStrategy;
$this->app->singleton('asset.version_strategy', function () {
return new JsonManifestVersionStrategy(
public_path('build/release-manifest.json') // Path to Vite/Mix manifest
);
});
Extend Blade to support Symfony’s asset syntax:
// app/Providers/BladeServiceProvider.php
use Illuminate\Support\Facades\Blade;
Blade::directive('symfonyAsset', function ($path) {
return "<?php echo symfony_asset({$path}); ?>";
});
Usage:
<script src="{{ symfonyAsset('js/symfony-bundle.js') }}"></script>
Dependency Conflicts
symfony/http-foundation conflicts with Laravel’s illuminate/http.composer why-not symfony/http-foundation to identify conflicts. Isolate Symfony dependencies in a separate module or use replace in composer.json.PHP Version Mismatch
symfony/asset v8+ requires PHP ≥8.4, but Laravel 11 targets PHP 8.2–8.3.Routing Conflicts
AssetMapper may generate URLs that conflict with Laravel’s routing (e.g., missing trailing slashes).PathPackage to normalize paths:
use Symfony\Component\Asset\PathPackage;
$packages->addPackage(new class extends PathPackage {
public function getUrl($path): string
{
return parent::getUrl($path) . (str_ends_with($path, '/') ? '' : '/');
}
});
Manifest File Paths
JsonManifestVersionStrategy expects a Symfony-style manifest (e.g., public/build/release.json), but Laravel’s Vite/Mix outputs mix-manifest.json or asset-manifest.json.use Symfony\Component\Asset\VersionStrategy\VersionStrategyInterface;
class LaravelManifestVersionStrategy implements VersionStrategyInterface
{
public function getVersion(string $path): string
{
$manifest = json_decode(file_get_contents(public_path('build/asset-manifest.json')), true);
return $manifest[$path] ?? '';
}
}
Blade vs. Twig
asset() in Twig) won’t work in Blade.asset() or create a Blade directive (as shown above).Cache Invalidation
php artisan cache:clear) may break asset URLs.How can I help you explore Laravel packages today?