Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Asset Laravel Package

symfony/asset

Symfony Asset Component generates URLs for web assets (CSS, JS, images) with built-in versioning for cache busting. Supports base paths, packages, and CDNs to keep asset links consistent across environments and deployments.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package:
    composer require symfony/asset
    
  2. Basic Usage in Blade:
    @inject('asset', 'Symfony\Component\Asset\Packages')
    <link href="{{ $asset->getUrl('css/app.css') }}" rel="stylesheet">
    
  3. Register the Service Provider (optional, for global access):
    // config/app.php
    'providers' => [
        Symfony\Component\Asset\AssetServiceProvider::class,
    ],
    
    Then access via asset() helper (if using Symfony’s bridge):
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
    

First Use Case: Cache-Busting with Fingerprinting

Enable versioning for a single file:

use Symfony\Component\Asset\PathPackage;

$package = new PathPackage(public_path(), true); // true = enable versioning
echo $package->getUrl('css/app.css');
// Output: /css/app.css?id=abc123 (or similar hash)

Key Starting Points

  • Symfony Asset Documentation
  • Laravel Integration: Use symfony/asset alongside laravel-mix or vite-laravel for hybrid versioning.
  • Debugging: Disable versioning in dev environments by passing false to PathPackage.

Implementation Patterns

Core Workflows

1. Static Asset Versioning

// app/Providers/AppServiceProvider.php
public function register()
{
    $this->app->singleton('asset.package', function () {
        return new PathPackage(public_path(), config('app.env') !== 'local');
    });
}

Blade Usage:

@inject('asset', 'asset.package')
<link href="{{ $asset->getUrl('js/main.js') }}" rel="stylesheet">

2. Dynamic Asset Paths (Theming/CDN)

$package = new PathPackage(public_path(), false, [
    'base_urls' => ['https://cdn.example.com'],
    'base_paths' => ['/themes/current'],
]);
echo $package->getUrl('css/styles.css');
// Output: https://cdn.example.com/themes/current/css/styles.css

3. Integration with Laravel Mix

Use JsonManifestVersionStrategy for Mix-manifest compatibility:

use Symfony\Component\Asset\JsonManifestVersionStrategy;

$strategy = new JsonManifestVersionStrategy(public_path('mix-manifest.json'));
$package = new PathPackage(public_path(), false, [], $strategy);
echo $package->getUrl('js/app.js');
// Output: /js/app.js?id=abc123 (from mix-manifest.json)

4. Middleware for Global Asset Rewriting

// app/Http/Middleware/AssetMiddleware.php
public function handle($request, Closure $next)
{
    $response = $next($request);
    $response->headers->set('Content-Type', 'text/html');
    $dom = new \DOMDocument();
    @$dom->loadHTML($response->getContent());
    $xpath = new \DOMXPath($dom);
    foreach ($xpath->query('//link[@href]') as $node) {
        $href = $node->getAttribute('href');
        $node->setAttribute('href', $this->app['asset.package']->getUrl($href));
    }
    $response->setContent($dom->saveHTML());
    return $response;
}

Integration Tips

  • Vite/Laravel: Use JsonManifestVersionStrategy with Vite’s asset-manifest.json.
  • Blade Directives: Create a custom directive for cleaner syntax:
    Blade::directive('asset', function ($expression) {
        return "<?php echo app('asset.package')->getUrl({$expression}); ?>";
    });
    
    Usage:
    <link href="@asset('css/app.css')" rel="stylesheet">
    
  • Caching: Cache the Packages instance in Laravel’s cache:
    $this->app->singleton('asset.package', function () {
        return Cache::remember('asset.package', now()->addHours(1), function () {
            return new PathPackage(public_path(), true);
        });
    });
    

Gotchas and Tips

Pitfalls

  1. Double Hashing with Mix:

    • If using both PathPackage (with true for versioning) and Laravel Mix, assets may get duplicate hashes.
    • Fix: Use JsonManifestVersionStrategy to defer to Mix’s hashes.
  2. Case-Sensitive Paths:

    • On Linux servers, /CSS/App.css and /css/app.css are treated as different files.
    • Fix: Normalize paths in PathPackage or use strtolower() in URLs.
  3. Strict Mode Exceptions:

    • JsonManifestVersionStrategy throws exceptions if mix-manifest.json is missing in strict mode.
    • Fix: Set strict: false in the strategy constructor.
  4. Base URL Conflicts:

    • Mix/Vite may generate absolute URLs (e.g., https://example.com/js/app.js), conflicting with base_urls.
    • Fix: Use JsonManifestVersionStrategy or manually strip protocols from Mix paths.

Debugging Tips

  • Disable Versioning in Dev:
    $package = new PathPackage(public_path(), config('app.env') === 'production');
    
  • Log Generated URLs:
    $url = $package->getUrl('css/app.css');
    \Log::debug("Asset URL: {$url}");
    
  • Check Manifest Files: Ensure mix-manifest.json or asset-manifest.json exists and is readable.

Extension Points

  1. Custom Version Strategies:

    class CustomVersionStrategy implements VersionStrategyInterface
    {
        public function getVersion(string $path): string
        {
            return filemtime(public_path($path));
        }
    }
    

    Usage:

    $package = new PathPackage(public_path(), false, [], new CustomVersionStrategy());
    
  2. Package Decorators: Extend Packages to add logic (e.g., analytics tracking):

    class AnalyticsPackage implements PackagesInterface
    {
        private $decorated;
    
        public function __construct(PackagesInterface $decorated)
        {
            $this->decorated = $decorated;
        }
    
        public function getUrl($path)
        {
            $url = $this->decorated->getUrl($path);
            // Add UTM parameters or other logic
            return $url.'?utm_source=analytics';
        }
    }
    

    Register as a decorator in Laravel’s service container.

  3. Event Listeners: Listen to AssetUrlGenerated events (if using Symfony’s event system) to modify URLs globally.

Performance Quirks

  • Filemtime Overhead: PathPackage uses filemtime() for versioning, which can be slow for many files.
    • Optimization: Cache filemtime results or use a database-backed version strategy.
  • Memory Usage: Large Packages instances (e.g., thousands of assets) may consume memory.
    • Fix: Lazy-load assets or use a database-backed solution.

Laravel-Specific Tips

  • Asset Helper Override: Override Laravel’s asset() helper to use symfony/asset:
    // app/Helpers/AssetHelper.php
    if (!function_exists('asset')) {
        function asset($path)
        {
            return app('asset.package')->getUrl($path);
        }
    }
    
  • Configurable Versioning: Add to config/app.php:
    'asset' => [
        'versioning' => env('APP_ENV') !== 'local',
        'base_url' => env('ASSET_BASE_URL', null),
    ],
    
    Then use in AppServiceProvider:
    $package = new PathPackage(
        public_path(),
        config('app.asset.versioning'),
        ['base_urls' => [config('app.asset.base_url')]]
    );
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope