Laravel Media Library

repository·main·Indexed 27 days ago

https://github.com/spatie/laravel-medialibrary

A Laravel package to associate files (images, PDFs, etc.) with Eloquent models. It provides an API for managing media collections, handling uploads, and utilizing different filesystems. Key features include media conversions, event listeners for file operations, custom URL generation, and the ability to attach media or conversions directly to Laravel Mailables.

Tokens
35.4K
Snippets
119
Records
190
Agent score
90%

What's inside laravel-medialibrary

  1. Understand the Responsive Images technique

    main

    The Laravel MediaLibrary uses a responsive images technique to optimize loading. It works by:

    1. Rendering an <img> tag with multiple srcset values.
    2. Using an initial sizes="1px" attribute to render an inline base64-encoded SVG placeholder first.
    3. Using JavaScript to update the sizes attribute to the actual width of the image in the layout once the page has loaded.
    4. Using a vw (viewport width) value for the updated width, which allows the browser to load larger image versions automatically when the browser window is upscaled.

    To see this in action, you can throttle your network in Chrome and disable the cache, or resize your browser window to trigger different image loads.

  2. Upgrade from v10 to v11

    main

    When upgrading to v11, note the following breaking changes:

    • Image Conversions: The package now uses Image v3. You must update your image conversion syntax to match the new requirements. Refer to the Spatie Image v3 documentation.
    • Event Names: All event names now include an Event suffix. For example, Spatie\MediaLibrary\MediaCollections\Events\MediaHasBeenAdded has been renamed to Spatie\MediaLibrary\MediaCollections\Events\MediaHasBeenAddedEvent.
  3. Define a single media conversion

    main

    To create derived versions of images (like thumbnails), implement the registerMediaConversions method in your model. This method uses addMediaConversion(name) to define the transformation. Conversions are automatically triggered when supported file types (jpg, png, svg, webp, avif, pdf, mp4, mov, or webm) are added.

    By default, conversions are saved as jpg files, but you can override this using format() or keepOriginalImageFormat(). The library uses spatie/image internally for manipulations.

    use Illuminateoldsymbol<Database\}Eloquentoldsymbol<Modeloldsymbol<>;
    use Spatieoldsymbol<MediaLibraryoldsymbol<MediaCollectionsoldsymbol<Modelsoldsymbol<Mediaoldsymbol<>;
    use Spatieoldsymbol<MediaLibraryoldsymbol<HasMediaoldsymbol<;
    use Spatieoldsymbol<MediaLibraryoldsymbol<InteractsWithMediaoldsymbol<;
    
    class YourModel extends Model implements HasMedia
    {
        use InteractsWithMedia;
    
        public function registerMediaConversions(?Media $media = null): void
        {
            $this->addMediaConversion('thumb')
                  ->width(368)
                  ->height(232)
                  ->sharpen(10);
        }
    }
  4. Install image optimization tools

    main

    Media Library can automatically optimize converted images if specific binaries are installed on your system. Supported tools include jpegoptim, optipng, pngquant, svgo, gifsicle, and avifenc.

    Ubuntu

    sudo apt install jpegoptim optipng pngquant gifsicle libavif-bin
    npm install -g svgo

    Or using snap for svgo:

    sudo apt install jpegoptim optipng pngquant gifsicle libavif-bin
    sudo snap install svgo

    Alpine Linux

    apk add jpegoptim optipng pngquant gifsicle libavif-apps
    npm install -g svgo

    MacOS (Homebrew)

    brew install jpegoptim optipng pngquant svgo gifsicle libavif
  5. Use deferred conversions for faster responses

    main

    Use deferred() to schedule a conversion to run after the HTTP response has been sent to the browser. This uses Laravel's defer() helper. This is ideal for tasks like generating avatars where you want to avoid blocking the upload request, but the task is too heavy for a standard synchronous request.

    Requirement: Requires Laravel 11.23 or higher. For older versions, use queued() or nonQueued().

    public function registerMediaConversions(?Media $media = null): void
    {
        $this->addMediaConversion('thumb')
                ->width(368)
                ->height(232)
                ->deferred();
    }
  6. Customize naming for responsive image files

    main

    By default, responsive image files are named using the format: {original-file-name-without-extension}___{name-of-the-conversion}_{width}_{height}.{extension}.

    You can customize this by implementing a custom FileNamer class. Note that when customizing responsive filenames, you can only control the prefix of the name, as the library requires specific suffixes (conversion name, width, and height) to process responsive images correctly.

  7. Upgrade from v8 to v9

    main

    Upgrading from v8 to v9 involves several database and configuration changes:

    Database Migrations

    1. Add generated_conversions column: Add a json column named generated_conversions to the media table. You must migrate existing values from the generated_conversions key within the custom_properties column to this new column.
    2. Migration Command: Run php artisan make:migration AddGeneratedConversionsToMediaTable and use the provided migration logic to transfer data.

    Configuration Changes

    • File Namer: Rename the conversion_file_namer key in config/media-library.php to file_namer. This key now handles both conversions and responsive images. Update its value to Spatie\MediaLibrary\Support\FileNamer\DefaultFileNamer::class.
    • Config Sync: Review config/media-library.php and ensure any new options present in the package's default config are added to your local file.
    • Collection Serialization: If you return media collections directly from controllers or manually serialize them to JSON, set use_default_collection_serialization to true in config/media-library.php to maintain existing behavior.
    <?php
    
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\DB;
    use Illuminate\Support\Facades\Schema;
    use Spatie\MediaLibrary\MediaCollections\Models\Media;
    
    class AddGeneratedConversionsToMediaTable extends Migration {
        public function up() {
            if ( ! Schema::hasColumn( 'media', 'generated_conversions' ) ) {
                Schema::table( 'media', function ( Blueprint $table ) {
                    $table->json( 'generated_conversions' )->nullable();
                } );
            }
            
            Media::query()
                ->where(function ($query) {
                    $query->whereNull('generated_conversions')
                        ->orWhere('generated_conversions', '')
                        ->orWhereRaw("JSON_TYPE(generated_conversions) = 'NULL'");
                })
                ->whereRaw("JSON_LENGTH(custom_properties) > 0")
                ->update([
                    'generated_conversions' => DB::raw("JSON_EXTRACT(custom_properties, '$.generated_conversions')"),
                ]);
        }
    
        public function down() {
            Schema::table( 'media', function ( Blueprint $table ) {
                $table->dropColumn( 'generated_conversions' );
            } );
        }
    }