Top 5 Questions/Answers About Spatie MediaLibrary

Founder of QuickAdminPanel
Inside of our QuickAdminPanel generator, we use Spatie MediaLibrary package for file uploads. And our customers often ask as questions about it, so we decided to compile the most popular ones and answer them in one article. It can be useful for any Medialibrary user, even without QuickAdminPanel.
Question 1. Where are my files stored?
This question may be very simple, and also may be very complicated. Cause there are at least three configuration files where you can set this preference:
- config/medialibrary.php
- config/filesystems.php
- .env
By default, config/medialibrary.php doesn’t exist. It is created only if you run this command from the package installation tutorial:
php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="config"
But even if we don’t have this config file published, the package still takes the default values from it’s core code in the /vendor folder. So let’s take a look at these default values.
Again, from their documentation – this is the default content of the config file (will skip the parameters irrelevant to this article):
return [ /* * The filesystems on which to store added files and derived images by default. Choose * one or more of the filesystems you've configured in config/filesystems.php. */ 'disk_name' => 'public', /* * The class that contains the strategy for determining a media file's path. */ 'path_generator' => null, 's3' => [ /* * The domain that should be prepended when generating urls. */ 'domain' => 'https://xxxxxxx.s3.amazonaws.com', ], /* * The path where to store temporary files while performing image conversions. * If set to null, storage_path('medialibrary/temp') will be used. */ 'temporary_directory_path' => null, ];
In fact, we’re mostly interested in one main parameter ‘disk_name’, and by default it’s set to ‘public’.
Now, what does that mean?
It refers to public disk in config/filesystems.php:
'disks' => [ 'local' => [ 'driver' => 'local', 'root' => storage_path('app'), ], 'public' => [ 'driver' => 'local', 'root' => storage_path('app/public'), 'url' => env('APP_URL').'/storage', 'visibility' => 'public', ], 's3' => [ // ...
In other words, default MediaLibrary stores files in storage/app/public folder, creating subfolders inside for each Media entry:
If you want to change that location, you have multiple options:
- Change config/filesystems.php file’s public disk parameters to some other folders, for example ‘root’ => public_path(‘uploads’),;
- Publish Medialibrary config with the command mentioned above, and change config/medialibrary.php disk_name from ‘public’ to whatever other disk you want;
- Add some variables to .env file and use env() function in config files, so every teammate/server would have different folders for upload.
You can read more about file storage in our other popular article:
File Upload in Laravel: The Ultimate Guide
Question 2. Why are my files not shown? 404 error?
Partly related to the first question about file storage and how it works, not only in Medialibrary, but generally in Laravel.
By default, if you store file XXXXX.jpg in storage/app/public, you should be able to access it with URL /storage/XXXXX.jpg. But there’s a catch – first time trying to load it, will give you a 404 error:
That’s actually a good thing – the whole purpose of /storage folder is to save files to NOT be available to public by default, so it’s a security protection.
To make it work for public disk, you need to run this command, as described in the official Laravel documentation:
php artisan storage:link
It creates a symlink file in /public folder, which tells the operating system that URL /storage/XXXXX.jpg should be actually taken from /storage/app/public/XXXXX.jpg.
Question 3. How to generate/customize thumbnails?
This is a question I’ve answered already in this YouTube video:
But answering in text format, it’s a very simple solution – in your Model you need to add a method registerMediaConversions().
For example, you want to add 50×50 thumbnails to every upload for User model. So you add this to app/User.php:
use Spatie\MediaLibrary\Models\Media; // ... public function registerMediaConversions(Media $media = null) { $this->addMediaConversion('thumb')->width(50)->height(50); }
And then you can call that thumbnail by the name assigned here, which is ‘thumb’:
$user = User::find(1); $mediaItems = $user->getMedia('images'); $mediaItems[0]->getUrl('thumb');
Question 4. How to query Media relationships in Eloquent?
Sometimes you need to retrieve media files along with your main model, in one Eloquent query.
Something, like… User::with(‘media’)->first();, but there’s no “media” as relationship. Should it be hasMany, or belongsToMany, or something else?
Medialibrary stores data in media database table with Polymorphic relationships. I also have a video on this topic:
So, to query the Media files for a User, we should add this to app/User.php:
use Spatie\MediaLibrary\Models\Media; class User extends Model implements HasMedia { /** * Get all of the user's images. */ public function media() { return $this->morphMany(Media::class, 'model'); }
That ‘model’ part refers to two fields: media.model_id and media.model_type.
And now, we can do exactly the thing posted above:
$user = User::with('media')->find(1); foreach ($user->media as $mediaFile) { // ...
Question 5. Why artisan migrate doesn’t work with MediaLibrary?
Probably the most often question asked by our customers. When they run the migrations, generated by our QuickAdminPanel, this error sometimes appears:
The answer here is pretty simple – here’s a quote from the Requirements section:
This package uses ‘json’ columns. MySQL 5.7 or higher is required.
So no way around it, you have to upgrade MySQL version, or switch from MariaDB (or other DB you’re using) to MySQL 5.7+.
There are problems with some web-server packages like XAMPP that switch on MariaDB by default, so check their documentation how to turn it off.
These were the most typical questions about Medialibrary, but you can also read its official documentation, it’s pretty well written.
Try our QuickAdminPanel generator!
15 Comments
Leave a Reply Cancel reply
Recent Posts
Try our QuickAdminPanel Generator!
How it works:
1. Generate panel online
No coding required, you just choose menu items.
2. Download code & install locally
Install with simple "composer install" and "php artisan migrate".
3. Customize anything!
We give all the code, so you can change anything after download.
Can the media file’s name be changed at time of upload? I’d like my users to be able to change the attachment filename as part of the upload process.
File UPLOAD process is running even before Medialibrary steps in, this package is only for ASSOCIATION with already uploaded files. In our QuickAdminPanel, for example, we use Dropzone.js and back-end part is done in generated file app/Http/Controllers/Traits/MediaUploadingTrait.php, specifically on these lines:
So you can customize that part. But not sure how would you give your USERS ability to change filenames, it requires changes in Dropzone.js script, too.
Read more about our Dropzone+Spatie approach here: https://laraveldaily.com/multiple-file-upload-with-dropzone-js-and-laravel-medialibrary-package/
Great article, found a lot of useful info about the questions I couldn’t google out and find answers anywhere else. You mentioned that files are stored in a new sub-folder each time, how can I overwrite this to just upload to storage/app/uploads without creating the subfolders?
I don’t think this package has this ability. Cause creating subfolders allows to solve the problem of diplicate file names, if you store everything into one folder then files may duplicate.
Thanks for the info; especially the command at the last part of the second question, really helped me out. Keep up the great work!
Good article, just a question.
How can I delete a media file?
https://docs.spatie.be/laravel-medialibrary/v8/basic-usage/retrieving-media/#main
You can remove something from the library by simply calling delete on an instance of Media: $mediaItems[0]->delete();
OR
Deleting a model with associated media will also delete all associated files.
$yourModel->delete(); // all associated files will be deleted as well
When I executed the command “composer install” it hangs the installation, never ending.
If I remove the line “spatie/laravel-medialibrary”: “^7.19”, of my composer.json the installation finish ok, but I can use the CRUD with photo type of data, it send mi the Error: the Interface ‘Spatie\MediaLibrary\HasMedia\HasMedia’ not found.
Pleas help me, sorry about my english.
Hi Omar,
Now separately run “composer require spatie/laravel-medialibrary:^7.19” and it should work.
I can not resolve the view of my Files, I executed the php artisan storage: link and it does not generate any changes, it throws me an error, Object not located, 404 error
hi mr Povilas
when i try to edit record with images
it give image name and dont preview image
Hi.. Do you know how to handle regenerate same conversation but different format. Let say currently Conversion A using png format. But, I want change to jpg. However when I regenerate, it not delete the old png image. How to tackle this problem? Thanks in advance.
In the database I see media_title, media_source, media_author, date_downloaded, date_listed, media_description. I seem to be missing where a command might be to set those built in like there is with the custom_properties having “->withCustomProperties()”.
Is there commands to easily set this stuff all in a single line or do I need to store a reference to the mediaItem and set them in another way?
I use quick admin panel and I use the Spatie Media Library from the software. I can upload images on desktop but when I do it through a mobile device it acts like it loaded but no image appears (no errors- just nothing in database). Like I said it works just fine on desktop but nothing happens with mobile. Any help would be great!
hello dear
I can change size of image that store as (thumb and preview) form 50×50 to 150×150 ?