elegantly/laravel-media
A media library for Laravel that handles file uploads, image conversions, and storage across disks. Attach media to Eloquent models, generate responsive images, and manage assets with a clean, fluent API. Ideal for apps needing flexible, organized media management without extra boilerplate.
Install the package:
composer require elegantly/laravel-media
Publish configuration and migrations, then migrate:
php artisan vendor:publish --tag="laravel-media-config"
php artisan vendor:publish --tag="laravel-media-migrations"
php artisan migrate
If the tags differ, run php artisan vendor:publish and select the Elegantly\Media provider.
Configure the default disk and storage paths in config/media.php. For local public files:
php artisan storage:link
Add the package trait to the model that owns media:
use Elegantly\Media\Concerns\HasMedia; // verify namespace in the README
class Post extends Model
{
use HasMedia;
}
First use case — attach an uploaded cover image and render it:
$post->addMediaFromRequest('cover')
->toMediaCollection('cover');
$url = $post->getFirstMediaUrl('cover');
Verify exact method names against the package README; the trait exposes a media relationship and collection helpers.
Where to look first:
README.md quickstart and API examples.config/media.php for disk, path, conversions, queue settings, and model bindings.media table schema and polymorphic columns.Model-centric collections. Attach media directly to Eloquent models and use named collections for different roles:
$post->addMediaFromRequest('hero')->toMediaCollection('hero');
$post->addMedia($request->file('gallery'))->toMediaCollection('gallery');
Request and disk sources. Handle form uploads, existing files, and external sources through the same media pipeline:
$post->addMediaFromRequest('document')->toMediaCollection('documents');
$post->addMediaFromDisk('imports/catalog.pdf', 'local')->toMediaCollection('documents');
Conversions and responsive images. Define thumbnails or derivative sizes in one place, generate them on upload, and render URLs/srcsets in Blade. Use queued conversions in production and synchronous generation only in tests or local development.
Per-collection storage rules. Keep public images on a public disk and private documents on a private disk. If the package supports per-collection disk/path configuration, prefer that over global config changes.
Blade and API output. Centralize URL rendering through package helpers or a small presenter so templates do not depend on storage internals:
<img src="{{ $post->getFirstMediaUrl('hero') }}" alt="">
Livewire/Filament/Inertia integration. Treat media uploads as a two-step workflow: upload the file, then attach it to the model after validation. On edit screens, expose existing media and support explicit removal so replaced files are deleted rather than orphaned.
Testing. Use Storage::fake() and RefreshDatabase, then assert both database records and stored files:
Storage::fake('public');
$post->addMediaFromRequest('cover')->toMediaCollection('cover');
$this->assertDatabaseHas('media', ['model_id' => $post->id]);
Storage::disk('public')->assertExists(/* path from media record */);
Cleanup and lifecycle. Add model observers or scheduled jobs to remove files when models or media records are deleted. This is especially important for user-generated content and multi-tenant apps.
composer.json.spatie/laravel-medialibrary, but method names, traits, and conversion behavior can differ. Read the README and service provider first.config/media.php, run php artisan config:clear. In production, redeploy with php artisan config:cache.APP_URL, or storage:link is wrong. Check the generated path against storage/app/public.upload_max_filesize and post_max_size. For large assets, consider direct-to-S3 uploads.media table, the configured disk path, storage/logs/laravel.log, and failed jobs. Confirm the collection name passed to the trait exactly matches the name used when retrieving media.How can I help you explore Laravel packages today?