Weave 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. Install the Package

    composer require nette/assets
    
  2. 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. Create a Blade Directive Add this to AppServiceProvider's boot():

    Blade::directive('asset', function ($expression) {
        return "<?php echo app('Nette\\AssetManager')->link((string) {$expression}; ?>";
    });
    
  4. First Usage Replace hardcoded paths in Blade:

    <link rel="stylesheet" href="{{ asset('css/main.css') }}">
    <script src="{{ asset('js/app.js') }}"></script>
    

First Use Case: Font Optimization

// In a controller or service
$fontAsset = $this->app->make(AssetManager::class)
    ->createFontAsset('fonts/Inter.woff2')
    ->setCrossOrigin('anonymous');

echo $fontAsset->getTag(); // <link rel="preload" href="/fonts/Inter.woff2?v=1.23" as="font" type="font/woff2" crossorigin="anonymous">

Implementation Patterns

1. Asset Registration Workflows

Static Assets (CSS/JS)

// Register a directory (e.g., public/css)
$assetManager->addProvider(new \Nette\AssetManager\Providers\DirectoryProvider(
    public_path('css'),
    'css'
));

// Blade usage:
<link rel="stylesheet" href="{{ asset('css/main.css') }}">

Dynamic Assets (User Uploads)

// Custom storage adapter (e.g., S3)
$assetManager->setStorage(new \Nette\AssetManager\Storage\S3Storage(
    $s3Client,
    'my-bucket',
    'https://cdn.example.com'
));

// Generate a signed URL for a user-uploaded file
$userAsset = $assetManager->createAsset('/uploads/avatar.jpg');
$userAsset->setExpires('+1 hour');
echo $userAsset->getUrl();

2. Environment-Specific Config

// In AppServiceProvider
$assetManager = new AssetManager();
$assetManager->setBasePath(public_path());

// Disable versioning in development
if (app()->environment('development')) {
    $assetManager->setVersioning(false);
}

// Enable preloading for production
if (app()->environment('production')) {
    $assetManager->setPreload(['fonts/Inter.woff2']);
}

3. Vite/Mix Integration

Development Proxying

// Register Vite dev server mapper
$assetManager->addMapper(new \Nette\AssetManager\Mappers\ViteMapper(
    'http://localhost:5173',
    ['css', 'js'] // Only proxy these extensions
));

// Blade usage (points to Vite dev server)
<link rel="stylesheet" href="{{ asset('resources/css/app.css') }}">

Production Builds

// Register built assets (after running `npm run build`)
$assetManager->addProvider(new \Nette\AssetManager\Providers\DirectoryProvider(
    public_path('build'),
    'build'
));

// Blade usage (points to compiled files)
<script src="{{ asset('build/app.js') }}"></script>

4. Blade Directives for Reusability

// Add a directive for font assets
Blade::directive('font', function ($expression) {
    return "<?php echo app('Nette\\AssetManager')->createFontAsset((string) {$expression})->getTag(); ?>";
});

// Usage in Blade:
@font('fonts/Inter.woff2', ['crossorigin' => 'anonymous'])

5. Nonce Integration for CSP

// In a middleware or service
$assetManager = app(AssetManager::class);
$nonce = $assetManager->generateNonce();

// Store nonce in session/Blade
session(['asset_nonce' => $nonce]);

// Blade usage:
<script src="{{ asset('js/app.js')->withNonce(session('asset_nonce')) }}"></script>

Gotchas and Tips

Pitfalls

  1. Path Resolution Failures

    • Issue: Assets not found due to incorrect base paths.
    • Fix: Always use absolute paths (e.g., public_path('css')) and validate directories during boot.
    • Debug: Enable AssetManager::setDebugMode(true) to log missing assets.
  2. Versioning Conflicts

    • Issue: Global versioning (?v=1.0) may break Vite/Mix hashed filenames.
    • Fix: Disable versioning in development or use file-based hashing:
      $assetManager->setVersioning(function ($asset) {
          return md5($asset->getUrl());
      });
      
  3. Font Loading Blockers

    • Issue: WOFF2 fonts may fail to load without crossorigin.
    • Fix: Always set crossorigin for external fonts:
      $fontAsset->setCrossOrigin('anonymous');
      
  4. Caching Headaches

    • Issue: Stale assets in production due to aggressive caching.
    • Fix: Use Laravel’s cache tags or implement a cache-busting header:
      $assetManager->setCacheControl('public, max-age=31536000, immutable');
      
  5. Vite/Mix Mismatches

    • Issue: Vite’s @vite() directives won’t work with nette/assets.
    • Fix: Replace @vite() with @asset() and manually handle Vite’s manifest:
      // Parse Vite's manifest.json and register assets
      $manifest = json_decode(file_get_contents(public_path('build/manifest.json')), true);
      foreach ($manifest as $entry => $hash) {
          $assetManager->addProvider(new \Nette\AssetManager\Providers\StaticProvider(
              "build/{$hash}",
              $entry
          ));
      }
      

Debugging Tips

  • Enable Debug Mode:
    $assetManager->setDebugMode(true); // Logs missing assets to storage/logs/nette-assets.log
    
  • Inspect Asset Tags:
    $asset = $assetManager->createAsset('css/main.css');
    dump($asset->getTag()); // Inspect generated HTML
    
  • Check Storage Backend:
    dump($assetManager->getStorage()->getAsset('css/main.css')); // Verify file exists
    

Extension Points

  1. Custom Storage Adapters Implement \Nette\AssetManager\IStorage for S3, Azure, etc.:

    class CustomStorage implements IStorage {
        public function getAsset(string $path): ?string {
            // Fetch from custom backend
        }
        public function getUrl(string $path): string {
            // Generate signed URL
        }
    }
    
  2. Asset Mappers Extend \Nette\AssetManager\IMapper for custom URL transformations:

    class CustomMapper implements IMapper {
        public function map(string $asset): ?string {
            return str_replace('old-', 'new-', $asset);
        }
    }
    
  3. Blade Directives Create reusable directives for common assets:

    Blade::directive('icon', function ($expression) {
        return "<?php echo app('Nette\\AssetManager')->createAsset('icons/{$expression}')->getTag(); ?>";
    });
    

Performance Optimizations

  • Preload Critical Assets:
    $assetManager->setPreload([
        'fonts/Inter.woff2',
        'css/main.css'
    ]);
    
  • Lazy-Load Non-Critical JS:
    $asset = $assetManager->createAsset('js/lazy.js');
    $asset->setAttribute('loading', 'lazy');
    echo $asset->getTag();
    
  • Cache-Control Headers:
    $assetManager->setCacheControl('public, max-age=31536000, immutable');
    

Laravel-Specific Quirks

  1. Service Container Integration Bind the AssetManager to Laravel’s container for dependency injection:

    $this->app->bind(\Nette\AssetManager::class, function ($app) {
        $assetManager = new \Nette\AssetManager();
        $assetManager->setBasePath($app->basePath('public'));
        return $assetManager;
    });
    
  2. View Composers Inject assets into views via composers:

    View::composer('*', function ($view) {
        $view->with('cssAssets', [
            $
    
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.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style