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

Assets Laravel Package

nette/assets

Nette Assets is a lightweight asset pipeline for Nette apps. It helps you manage and reference CSS/JS, handle versioning/cache busting, and organize assets for development and production builds with a simple API and configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require nette/assets
    

    Add to composer.json under require or require-dev based on your needs.

  2. Basic Configuration: Register the AssetManager in AppServiceProvider's boot() method:

    use Nette\AssetManager;
    
    public function boot()
    {
        $this->app->singleton(AssetManager::class, function ($app) {
            $assetManager = new AssetManager();
            $assetManager->setBasePath(public_path());
            return $assetManager;
        });
    }
    
  3. First Use Case: Create a Blade directive for easy asset references:

    // In AppServiceProvider
    Blade::directive('asset', function ($expression) {
        return "<?php echo app('Nette\\AssetManager')->link(" . $expression . "); ?>";
    });
    

    Now use @asset('css/main.css') in Blade templates.

  4. Verify Versioning: Access an asset in production to confirm automatic versioning (e.g., /css/main.css?v=12345).


Implementation Patterns

Core Workflows

1. Static Asset Management

  • CSS/JS/Fonts: Reference assets via @asset('path/to/file.ext') in Blade.
  • Versioning: Enable/disable globally in AssetManager:
    $assetManager->setAutoVersioning(true); // Default: true in production
    

2. Font Optimization

  • WOFF2 Support: Use FontAsset for font files:
    $font = $assetManager->createFontAsset('fonts/Inter.woff2');
    $font->setCrossOrigin('anonymous'); // For CDN-hosted fonts
    echo $font->getTag();
    
  • Preloading: Manually add <link rel="preload"> for critical fonts in Blade:
    @asset('fonts/Inter.woff2')->withAttributes(['as' => 'font', 'crossorigin'])
    

3. Vite/Mix Integration

  • Dev Server Proxying (v1.0.4+):
    $assetManager->addMapper(new \Nette\AssetMapper\ViteMapper('http://localhost:5173'));
    
  • Production Builds: Register build directories:
    $assetManager->addDirectory(public_path('build'));
    

4. Dynamic Asset Generation

  • Service Integration: Inject AssetManager into controllers/services:
    public function __construct(private AssetManager $assetManager) {}
    
    public function getDynamicAsset()
    {
        return $this->assetManager->link("dynamic-assets/{$this->userId}.js");
    }
    

5. Nonce for CSP

  • Generate nonces in Blade:
    @asset('script.js')->withNonce(csp_nonce())
    
  • Ensure csp_nonce() is defined in your CSP middleware.

Integration Tips

Laravel-Specific Adaptations

  1. Blade Directives: Extend the basic directive for attributes:

    Blade::directive('asset', function ($expression) {
        return "<?php echo app('Nette\\AssetManager')->link(" . $expression . ")->withAttributes(" . $expression . "Attributes); ?>";
    });
    

    Usage:

    @asset('script.js', ['defer' => true])
    
  2. Environment Awareness: Disable versioning in development:

    if (app()->environment('local')) {
        $assetManager->setAutoVersioning(false);
    }
    
  3. Custom Storage: Implement Nette\AssetManager\IStorage for S3/Azure:

    $assetManager->setStorage(new S3Storage($s3Client, 'my-bucket'));
    
  4. Asset Groups: Organize assets by context (e.g., admin vs. frontend):

    $adminAssets = new \Nette\AssetManager();
    $adminAssets->addDirectory(public_path('admin-assets'));
    

Performance Optimizations

  • Critical CSS/JS: Use AssetManager::createInlineAsset() for above-the-fold styles.
  • Cache Control: Leverage Laravel’s Response middleware to add Cache-Control headers:
    $assetManager->getAsset('main.css')->setCacheControl('public, max-age=31536000');
    

Gotchas and Tips

Pitfalls

  1. Path Resolution:

    • Issue: Relative paths may break if basePath isn’t set correctly.
    • Fix: Always use absolute paths (e.g., public_path('css/main.css')) or configure basePath:
      $assetManager->setBasePath(public_path());
      
  2. Versioning Conflicts:

    • Issue: Disabling versioning in production may serve stale assets.
    • Fix: Use file-based hashing for edge cases:
      $assetManager->setVersioningStrategy(new \Nette\AssetManager\FileVersioningStrategy());
      
  3. Vite/Mix Sync:

    • Issue: Vite’s asset hashing may conflict with nette/assets versioning.
    • Fix: Disable versioning for Vite assets:
      $assetManager->addMapper(new ViteMapper('http://localhost:5173'))
                   ->setVersioning(false);
      
  4. Font Loading:

    • Issue: Missing crossorigin on self-hosted fonts may block rendering.
    • Fix: Enforce it globally:
      $fontAsset = $assetManager->createFontAsset('fonts/Inter.woff2');
      $fontAsset->setCrossOrigin('use-credentials'); // Or 'anonymous'
      
  5. Blade Caching:

    • Issue: Cached Blade views may not reflect asset changes.
    • Fix: Clear Blade cache after asset updates:
      php artisan view:clear
      

Debugging Tips

  1. Asset Existence: Check if an asset exists before linking:

    if ($assetManager->hasAsset('missing.css')) {
        echo $assetManager->link('missing.css');
    }
    
  2. Versioning Debug: Inspect the generated URL to verify versioning:

    dd($assetManager->link('main.css')); // Should show ?v=12345
    
  3. Storage Backend: Verify custom storage works:

    $assetManager->setStorage(new CustomStorage());
    dd($assetManager->getAsset('test.txt')->getUrl());
    
  4. Vite Dev Server: Ensure the Vite dev server is running and the mapper URL is correct:

    $mapper = new ViteMapper('http://localhost:5173');
    dd($mapper->getUrl('app.js')); // Should proxy to Vite
    

Extension Points

  1. Custom Asset Types: Extend Nette\AssetManager\Asset for specialized assets (e.g., SVG sprites):

    class SpriteAsset extends \Nette\AssetManager\Asset {
        public function getTag(): string {
            return sprintf('<img src="%s" class="sprite">', $this->getUrl());
        }
    }
    
  2. Storage Adapters: Implement Nette\AssetManager\IStorage for custom backends:

    class S3Storage implements IStorage {
        public function url(string $path): string {
            return "https://my-bucket.s3.amazonaws.com/{$path}";
        }
        // Implement other methods...
    }
    
  3. Blade Extensions: Add more directives for common use cases:

    Blade::directive('preload', function ($expression) {
        return "<?php echo app('Nette\\AssetManager')->createAsset(" . $expression . ")->getPreloadTag(); ?>";
    });
    
  4. Middleware Integration: Add asset-specific headers via middleware:

    public function handle($request, Closure $next) {
        if ($request->isAssetRequest()) {
            $response = $next($request);
            $response->header('Cache-Control', 'public, max-age=31536000');
            return $response;
        }
        return $next($request);
    }
    
  5. Testing: Mock AssetManager in tests:

    $assetManager = Mockery::mock(AssetManager::class);
    $assetManager->shouldReceive('link')->with('test.css')->andReturn('<link href="/test.css?v=123">');
    $this->app->instance(AssetManager::class, $assetManager);
    
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.
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver