For file uploads, there's a very popular JavaScript library called FilePond. How to use it in Laravel? We'll talk about using it in create/edit forms, previewing the images, and then will try to use tools like Spatie Media Library, Amazon S3 and Livewire. So, let's get into it!
Step-by-step, we will cover these topics:
- File Upload Form without FilePond
- Visual Change: Replace File Input with FilePond
- Process Upload with FilePond
- FilePond in Edit Form
- Uploading Multiple Files
- Using Spatie Media Library
- Uploading to Amazon S3
- Upload Directly to S3 With Livewire
Step 1. File Upload Form Without FilePond
First, let's set up the scene: we'll be working with a simple Task form with fields title and image:
Migration structure:
database/migrations/xxxx_create_tasks_table.php:
return new class extends Migration {
public function up()
{
Schema::create('tasks', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('image');
$table->timestamps();
});
}
};
Controller method for this form will be as simple as this:
app/Http/Controllers/TasksController.php:
class TasksController extends Controller
{
public function create()
{
return view('tasks.create');
}
public function store(TaskRequest $request)
{
Task::create($request->validated());
return redirect()->route('tasks.index');
}
}
For the front-end part, we will use Laravel Breeze as a starter kit...
Premium Members Only
This advanced tutorial is available exclusively to Laravel Daily Premium members.
Already a member? Login here
Premium membership includes:
Comments & Discussion
I followed the instructions but got stuck on the path when saving.
File not found at path
Pls, help me
Hey Povilas,
I try to create filapond with media library but with inertia and vue. I follow the steps but when upload the image, on finished show an error POST http://localhost:8000/image 500 (Internal Server Error). I create a gist with the full code here.
Sorry I don't have enough time to debug it for you personally. 500 error usually means the server misconfiguration. The error may be in the storage/logs/laravel.log file, maybe check it?
If not, I would strongly suggest to not use localhost:8000 for serious projects, instead use a proper web-server like, for example, Laravel Valet which will give you a proper domain name like project.test or something. Potentially, part of the problem is that you're using php artisan serve (I guess?) which is not configured enough for file uploads properly.
Excellent article. Would it be possible to use medialibrary for files that are persisted in the database (mysql), for example? What is your opinion to persist files in database? Do you believe it is a valid practice?
What should we do if we are uploading multiple images for multiple columns. For example, user_image, passport_image, driver_license_image. Do I need to write Filepond.create() and different routes for every image or Uploading Multiple images section of this post applies to it.
One useful case that I faced during this lesson is that when laravel debugbar installed filepond uploading not worked correctly. I didn't even think about that. But so confusing. After removing laravel debugbar my file upload feature is start working correctly. I think this case will be useful for other developers because I spent a lot of time to find the reason of error.
I am not understanding what is going on. I followed all the implementation steps with Livewire, but in the validation part, it always returns the error that "image" is required.
And there in the bucket on AWS appears the temporary folder.
And also analyzing the livewire event, the "image" => Livewire\TemporaryUploadedFile {#1907 ▼ +"disk": "s3" -test: false -originalName: "EXb52iQI1D9uuxMkjMXY0IWw9UC7mX-metaMTYuanBn-.jpg" -mimeType: "application/octet-stream" -error: 0 #hashName: null #storage: Illuminate\Filesystem\AwsS3V3Adapter {#2373 ▶}
Weird, sometimes the upload works, sometimes it doesn't.
From what I've checked, it seems that sometimes the validation takes place before the upload and the $image data has arrived there, and then the validation takes the $image as null.
NOTE: I'm not using submit, I'm doing it via event
process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
@this.upload('image', file, load, error, (progress) => {
Livewire.emit('coachAvatar::save');
console.log(progress.detail.progress);
})
},
Doing some research, I realized that I don't need to emit an event.
Just call an updated function directly in the component.
public function updatedImage()
{
//code
}
And it worked correctly.
Sorry for all these comments, but maybe it will help someone who likes mess like me kkkkk
Hello. I want to create a feature like the input field in main page of filepond ([https://pqina.nl/filepond/]). For the moment my code is like this. I want when i revert a file to stay in the input so after i can reupload it or remove it.
<div
wire:ignore
x-data
x-init="
FilePond.setOptions({
allowProcess: false,
allowRemove: false,
credits: false,
allowMultiple: {{ isset($attributes['multiple']) ? 'true' : 'false' }},
server: {
process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
@this.upload('{{ $attributes['wire:model'] }}', file, load, error, progress);
},
revert: (filename, load) => {
@this.removeUpload('{{ $attributes['wire:model'] }}', filename, load);
},
},
});
const test = FilePond.create($refs.input);
"
>
<input type="file" x-ref="input">
</div>
Nicely done! Havn't started the edit section yet but all is working great. Never used request classes but easy to google and figure out. Anyway my question is how to store the original filename from the request into the table? Found the FilePondPluginFileRename but with filepond's docs but I cant get it working. Is there a github for this tut? I can't find it. Thx!
Quite the same article here? Are the same author in medium? Or did they copied your article?
https://medium.com/@laravelprotips/laravel-file-upload-guide-harnessing-filepond-054a6b879bc7
I've found a type on the upload() method example for multiple images:
$path = $file->store('tmp', 'public');
should be
$path[] = $file->store('tmp', 'public');
Also (in my opinion), since it's a paths list, should be named paths, not path.
Hi Povilas,
Great Tutorial! Easy to follow and concise. One issue I encountered during the implementation is that, the image (file) field is getting populated with PHPDebugBar's HTML/JS. When I disable APP_DEBUG, no extra data is being populated.
I am using Barry's Laravel Debugbar. Have you come across the same issue? How to handle this without disabling the debug bar. Meanwhile, I'll try myself for a solution.
Thanks again for all your hard work!
To be honest, I don't remember looking at Debugbar at that moment, so even if I did have that problem, I didn't see it, so don't have a solution for you, unfortunately.
Solution for single image/file just return json response
And use filepond "process" callback function:
I actually experienced this and end up removing debugbar