Laravel Livewire Multiple Files Upload API with Loading and Preview Image
A newer version 1.2.0 is added to Laravel Livewire which consists of File Uploads Components. Before this feature, you have manually use create an event and pass the base64 data to the livewire component.
But in this newer version there is no need to do those steps as you can use WithFileUploads trait which will implicitly create a file object for you and you can also use this to validate, store and also display the preview of the selected image in the template itself.
Note
If you are looking for uploading files using Javascript Invocation in Livewire than you visit this post.
Table of Content
- Create New Laravel Project
- Install and Configure Livewire
- Include Livewire Assets into Blade Template
- Simple File Upload Component and View
- Multiple Files Upload Component, View and with Image Preview
- Project Structure
- Output
- Conclusion
Create New Laravel Project
Run below command to create a new Laravel Project.
composer create-project --prefer-dist laravel/laravel my_new_laravel
After successful installation navigates inside the project through the terminal.
Install and Configure Livewire
After Laravel Project is successfully installed run composer require livewire/livewire to install Livewire.
After this the next step is to publish the config and assets base URL file through which we can specify a custom assets path for livewire package.
php artisan vendor:publish --tag=livewire:config
The above command will publish a config file livewire.php in the config folder inside the project root.
php artisan vendor:publish --tag=livewire:assets
The above command will publish assets for livewire at the path public/vendor folder.
The Livewire official docs recommend adding post-autoload-dump into composer.json inside scripts as shown below.
{ "scripts": { "post-autoload-dump": [ "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", "@php artisan package:discover --ansi", "@php artisan vendor:publish --force --tag=livewire:assets --ansi" ] } }
Include Livewire Assets into Blade Template
Now you can start developing your project and the first thing you must do is to create a base template that contains livewire javascript assets.
For this let us first create a route.
Route::get('/', function () { return view('base'); });
Now create a base.blade.php inside: resources/views/base.blade.php
<html> <head> <title>Laravel File Upload</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script> @livewireStyles </head> <body> @livewireScripts </body> </html>
Simple File Upload Component and View
Now the basic setup is done the next thing is to create a simple file upload component and view for this run below command.
php artisan make:livewire file-upload
You’ll see a new file at app/Http/Livewire/FileUpload.php and view at resources/views/livewire/file-upload.blade.php.
After component and view get create you must include them inside base.blade.php.
@livewireStyles </head> <body> @livewire('file-upload') @livewireScripts </body>
Simple File Upload Snippet
resources/views/livewire/file-upload.blade.php
<div> <h2>File Upload Form</h2> <!-- Create File Upload Form --> <form wire:submit.prevent="uploadSelectedFile" > <div class="row"> <div class="col-md-3"> <label for="">Choose File</label> <input type="file" wire:model="profile_image" > <!-- Did a mistake here --> @error('profile_image') <span style="color:red;">{{ $message }}</span> @enderror </div> <div class="col-md-12"> <input type="submit" name="submit" value="Upload Image"> </div> </div> </form> </div>
app/Http/Livewire/FileUpload.php
<?php namespace App\Http\Livewire; use Livewire\Component; use Livewire\WithFileUploads; class FileUpload extends Component { use WithFileUploads; public $profile_image; public function uploadSelectedFile(){ $this->validate([ 'profile_image' => 'required|image', ]); $ext = $this->profile_image->getClientOriginalExtension(); dd($this->profile_image->storeAs('public/uploads', 'my-profile-pic2.'.$ext)); } public function render() { return view('livewire.file-upload'); } }
After this step is done goto URL http://localhost/my_new_laravel/public/ and there you’ll see a file upload form.
The uploaded files will be saved inside storage/app/public directory by folder name uploads.
Laravel will implicitly create the folder if does not exists.
Multiple Files Upload Component, View and with Image Preview
For uploading, multiple files use attribute multiple on the HTML file field.
Create a fresh Multiple File Upload Component with view
php artisan make:livewire multile-files-upload
Change the calling of component file-upload with below component in base.blade.php
<!-- Change from this --> @livewire('file-upload') <!-- TO this --> @livewire('multiple-files-upload')
Multiple Files Upload Snippet
resources\views\livewire\multiple-files-upload.blade.php
<div> <h2>Multiple Files Uploads</h2> <form wire:submit.prevent="uploadMultipleFiles" > <div class="row"> <div class="col-md-3"> <label for="">Slides</label> <input type="file" class="form-control" wire:model="slides" multiple > @error('slides.*') <span style="color: red;" >{{ $message }}</span> @enderror <h2>Preview Images</h2> <!-- Loading Message for Images --> <div wire:loading wire:target="slides">Uploading Slide Images...</div> @if( !empty( $slides ) ) <div> @foreach ( $slides as $slide ) <img src="{{ $slide->temporaryUrl() }}" alt="" style="width: 100px;" > @endforeach </div> @endif </div> <div class="col-md-12"> <button type="submit" class="btn btn-primary" >Upload Slides</button> </div> </div> </form> </div>
app\Http\Livewire\MultipleFilesUpload.php
<?php namespace App\Http\Livewire; use Livewire\Component; use Livewire\WithFileUploads; class MultipleFilesUpload extends Component { use WithFileUploads; public $slides=[]; public function uploadMultipleFiles(){ $this->validate([ 'slides.*' => 'image' ]); if( !empty( $this->slides ) ){ foreach( $this->slides as $slide ){ $slide->store('public/slides-images'); } } } public function render() { return view('livewire.multiple-files-upload'); } }
Initialize the public $slides=[]; as an array and after submitting validate each of the files using slides.*. Here the asterisk * means multiple items.
After successful validation loop over $slides and call store() methond on each $slide.
You’ll see that a new folder named slides-images will be created inside storage\app\public and this folder contains all the files you have uploaded.
Previewing Multiple Files before Upload
In template resources\views\livewire\multiple-files-upload.blade.php. The file field is mapped to wire:model=”slides” and onchange the livewire detects the files and displays them when we loop over each of them before the file is just ready to upload.
@if( !empty( $slides ) ) <div> @foreach ( $slides as $slide ) <img src="{{ $slide->temporaryUrl() }}" alt="" style="width: 100px;" > @endforeach </div> @endif
The path through which images are displayed are stored in $slide->temporaryUrl().
Show loading message before previewing the image
The simplest solution provided by livewire is to use wire:loading directive which has slides as a target.
<div wire:loading wire:target="slides">Uploading Slide Images...</div>
Output

Laravel Livewire multiple files uploads with loading message and previewing of the image before upload final output
Conclusion
In conclusion, you have reached the end of this post on the Laravel Livewire Multiple Files Upload API with Loading and Preview Image. For more information or queries comment below.




