How to Upload File using Livewire and Display Preview in Laravel

Livewire has provided the WithFileUploads trait for making the uploading process easier.

In this tutorial, I show how you can upload file using Livewire component and display a preview after upload in Laravel 9.

How to upload file using Livewire and display preview in Laravel


Contents

  1. Create Controller
  2. Create Route
  3. Create Livewire Component
  4. Create View
  5. Create symbolic link
  6. Output
  7. Conclusion

1. Create Controller

  • Create PagesController controller.
php artisan make:controller PagesController
  • Open app\Http\Controllers\PagesController.php file.
  • Create 1 method –
    • index() – Load index view.

Completed Code

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PagesController extends Controller
{
    public function index(){
        return view('index');
    }
}

2. Create Route

  • Open routes/web.php file.
  • Define 1 route –
    • / – Load index view.
<?php

use Illuminate\Support\Facades\Route;

use App\Http\Controllers\PagesController;

Route::get('/', [PagesController::class, 'index']);

3. Create Livewire Component

Create fileupload component –

php artisan make:livewire fileupload

This will create 2 files –

  • app/Http/Livewire/Fileupload.php
  • resources/views/livewire/fileupload.blade.php

Fileupload.php

  • Include Livewire\WithFileUploads; trait and Illuminate\Support\Facades\Storage;.
  • Create 5 class variables –
    • $file – For data binding.
    • $original_filename – Store uploading file original name.
    • $filepath – Store file path after upload for preview.
    • $success – Store upload status.
    • $isImage – Store boolean value according to file type.
  • Create 1 method –
    • save() – This method calls on <form > submit.

Reset the value of $status and $isImage. Define file validation. If file is successfully validated then read file name and assign it to $original_filename.

Upload the file to the files folder and assign the returned filename to $filename.

Check whether the file extension is image-type or not. If it is then assign true to $isImage. Assign 1 to $success.

Assign the upload file path to $filepath.

Completed Code

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use Livewire\WithFileUploads;
use Illuminate\Support\Facades\Storage;

class Fileupload extends Component
{

    use WithFileUploads;

    public $file;
    public $original_filename = "";
    public $filepath = "";
    public $success = 0;
    public $isImage = false;

    public function save() {
        // Reset value
        $this->success = 0;
        $this->isImage = false;

        // Validate
        $this->validate([
             'file' => 'required|mimes:png,jpg,jpeg,csv,pdf|max:2048', // 2MB Max
        ]);

        // Original File name
        $this->original_filename = $this->file->getClientOriginalName();

        // Upload file
        $filename = $this->file->store('files', 'public');

        // Check file extension is an image type
        $extension = strtolower($this->file->extension());
        $image_exts = array('png','jpg','jpeg');
        if(in_array($extension,$image_exts)){
             $this->isImage = true;
        }

        // Success
        $this->success = 1;

        // File path
        $this->filepath = Storage::url($filename);

    }

    public function render(){
        return view('livewire.fileupload');
    }
}

fileupload.blade.php

  • Display success message if $success == 1.
  • Create a <form > and add wire:submit.prevent="save".
  • Create a file element and add file model.
  • Display error message if file is not validated.
  • Create a submit button.
  • Display file preview if $success == 1.
  • If $isImage return true then use <img > to display file otherwise use <a > tag to display link.

Completed Code

<div>

    <!-- Success Message -->
    @if($success == 1)
        <div class="alert alert-success">
            Upload successfully
        </div>
    @endif

    <!-- Upload form -->
    <form wire:submit.prevent="save">
         <input type="file" wire:model="file">

         @error('file') 
             <div class="error text-danger">* {{ $message }}</div> 
         @enderror

        <div class="mt-2">
             <button class="btn btn-info " type="submit">Upload</button>
        </div>
    </form>

    <!-- File Preview -->
    <div class="mt-5">
         @if($success == 1)
              @if($isImage)
                   <img src="{{ asset($filepath) }}" width='200px;'>
              @else
                   <a href="{{ asset($filepath) }}">{{ $original_filename }}</a>
              @endif

         @endif
    </div>

</div>

4. Create View

Create index.blade.php file in resources/views/ folder.

Add fileupload component and include livewire style and script.

Completed Code

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>How to upload file using Livewire and display preview in Laravel</title>

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" >

    @livewireStyles
</head>
<body>

    <div class="container mt-5">
         <livewire:fileupload />
    </div>

    @livewireScripts
</body>
</html>

Run the following command to create the symbolic link if you have not created it in your project –

php artisan storage:link

6. Output

View Output


7. Conclusion

Update file validation according to your requirement and if you are allowing to upload large files then make sure to check upload_max_filesize and post_max_size in php.ini and update its value if required.

If you found this tutorial helpful then don't forget to share.

Leave a Comment