Laravel allows easy multiple file uploads with validation and storage. It improves user experience by securely handling files and supporting image previews in just a few steps.

Key Points

  • 85% of Laravel apps use built-in file storage for secure uploads and fast retrieval.
  • File size limit commonly set at 2MB–5MB, preventing 90% of upload-related errors.
  • Laravel has maintained a 95 %+ developer satisfaction rate over the last 5 years.
Digittrix Blog Author Image

Web Developer

Saloni

3 min read

Skilled web developer with 2+ years of hands-on experience delivering fast and functional websites.

image showcasing a laptop with Laravel logo and documents illustrating the concept of multiple file uploads in Laravel 8 or later

Introduction

In modern website development services, handling multiple file uploads efficiently is a common requirement for custom web development projects. Whether you're building a user dashboard, admin panel, or enterprise-level application, implementing a secure and intuitive file upload feature is crucial. Laravel, known for its elegance and developer-friendly syntax, offers a robust and scalable way to manage file uploads.

In this guide, we will walk you through the process of creating a multiple image/file upload feature using Laravel 8.x or later. This tutorial is designed for those looking to hire laravel developers or Front-end Developers for custom solutions, as well as Laravel enthusiasts aiming to expand their practical knowledge.

Let’s get started.

Prerequisites

Before diving in, make sure you have the following:

  • Laravel 8.x or later installed.

  • Basic understanding of Laravel routing, controllers, and Blade views.

  • Storage linked (storage/app/public to public/storage) via artisan command:
    php artisan storage:link

Step 1: Create the File Upload Form

In your Blade view file (resources/views/upload.blade.php), create a user-friendly form that allows users to upload multiple images. This step is critical in custom web development, especially when focusing on user experience, which Front-end Developers must consider.

upload.blade.php:

                                        <!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Image Upload </title>
   <style>
       body {
           font-family: Arial, sans-serif;
           margin: 30px;
           background-color: #f9f9f9;
       }

       .upload-wrapper {
           background: #fff;
           padding: 20px;
           border-radius: 8px;
           max-width: 600px;
           margin: auto;
           box-shadow: 0 0 10px rgba(0,0,0,0.1);
       }

       label {
           font-weight: bold;
           display: block;
           margin-bottom: 10px;
       }

       .file-input-group {
           display: flex;
           align-items: center;
           margin-bottom: 10px;
       }

       .file-input-group input[type="file"] {
           flex: 1;
       }

       .add-btn {
           background-color: #28a745;
           color: white;
           border: none;
           border-radius: 4px;
           margin-left: 10px;
           cursor: pointer;
           width: 30px;
           height: 30px;
           font-size: 18px;
       }

       .submit-btn {
           background-color: #007bff;
           color: white;
           border: none;
           padding: 10px 20px;
           margin-top: 15px;
           border-radius: 5px;
           cursor: pointer;
       }

       .preview-container {
           margin-top: 20px;
           display: flex;
           flex-wrap: wrap;
           gap: 10px;
       }

       .preview-container img {
           width: 100px;
           height: 100px;
           object-fit: cover;
           border: 1px solid #ccc;
           border-radius: 5px;
       }
   </style>
</head>
<body>

<div class="upload-wrapper">
   <form action="{{ route('upload.files') }}" method="POST" enctype="multipart/form-data">
       @csrf
       <label for="files">Choose images:</label>

       <div id="file-inputs">
           <div class="file-input-group">
               <input type="file" name="files[]" accept="image/*" onchange="previewImages(event)">
               <button type="button" class="add-btn" onclick="addFileInput()">+</button>
           </div>
       </div>

       <button type="submit" class="submit-btn">Upload</button>
   </form>

   <!-- Preview area -->
   <div id="image-preview" class="preview-container"></div>
</div>

<script>
   function addFileInput() {
       const fileInputsContainer = document.getElementById('file-inputs');
       const newInputGroup = document.createElement('div');
       newInputGroup.classList.add('file-input-group');
       const inputId = `input-${Date.now()}`;
       newInputGroup.innerHTML = `
           <input type="file" name="files[]" accept="image/*" onchange="previewImages(event)">
           <button type="button" class="add-btn" onclick="addFileInput()">+</button>
       `;
       fileInputsContainer.appendChild(newInputGroup);
   }

   function previewImages(event) {
       const files = event.target.files;
       const previewContainer = document.getElementById('image-preview');

       // Clear previous previews for this input
       for (let i = 0; i < files.length; i++) {
           if (!files[i].type.startsWith('image/')) continue;

           const reader = new FileReader();
           reader.onload = function(e) {
               const img = document.createElement('img');
               img.src = e.target.result;
               previewContainer.appendChild(img);
           };
           reader.readAsDataURL(files[i]);
       }
   }
</script>

</body>
</html>
                                        
                                    

Step 2: Define Routes

Add the following routes to your routes/web.php file to manage GET and POST requests:

                                        <?php
use App\Http\Controllers\FileUploadController;
Route::get('/upload', [FileUploadController::class, 'showForm']);
Route::post('/upload', [FileUploadController::class, 'uploadFiles'])->name('upload.files');
?>
                                        
                                    

Step 3: Create the Controller

Run the artisan command to generate a controller:

php artisan make:controller FileUploadController

Now, update your controller file: app/Http/Controllers/FileUploadController.php

                                        <?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class FileUploadController extends Controller
{
   public function showForm()
   {
       return view('upload');
   }
   public function uploadFiles(Request $request)
   {
       $request->validate([
           'files.*' => 'required|mimes:jpg,jpeg,png,pdf,docx|max:2048'
       ]);
         $uploadedFiles = [];
        if ($request->hasFile('files')) {
           foreach ($request->file('files') as $file) {
               $filename = time() . '_' . $file->getClientOriginalName();
               $path = $file->storeAs('uploads', $filename, 'public');
               $uploadedFiles[] = $path;
           }
       }
       return back()->with('success', 'Files uploaded successfully!')
                    ->with('files', $uploadedFiles);
 }
}
?>
                                        
                                    

This controller efficiently handles multiple file uploads while applying validation rules, an important feature in any secure custom web development service.

Step 4: Display Uploaded Files (Optional)

Create another view file to preview uploaded files after successful upload:

resources/views/uploadfilepreview.blade.php

                                        <!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Upload  Image preview</title>
   <style>
       body {
           font-family: Arial, sans-serif;
           margin: 30px;
           background-color: #f9f9f9;
       }

     </style>
</head>
<body>

   @if(session('success'))
       <p>{{ session('success') }}</p>
       <ul>
           @foreach(session('files') as $file)
               <li><a href="{{ asset('storage/' . $file) }}" target="_blank">{{ $file }}</a></li>
           @endforeach
       </ul>
   @endif

</body>
</html>
                                        
                                    

Key Benefits

Implementing multiple file uploads in Laravel offers several advantages for businesses and developers alike. Whether you're offering website development services or looking to build scalable web apps, here are the key benefits:

  • Excellent User Experience

  • Scalable for Large Projects

  • Built-In Security

  • Customizable Storage Options

  • Rapid Development

  • Developer-Friendly Structure

  • Improved Project Value

Final Words

Whether you're an entrepreneur looking to build scalable applications or a business aiming to enhance your website development services, mastering file uploads in Laravel is essential. This multiple file upload example not only demonstrates how to create an efficient feature using Laravel but also lays a strong foundation for custom web development.

If you're looking to expedite your development process or require expert assistance, you can hire Laravel developers or work alongside seasoned front-end developers to ensure your project upholds high-performance and security standards.

For more robust and scalable solutions, contemplate incorporating this functionality into a broader ecosystem featuring advanced validation, cloud storage and real-time feedback.

Do you want help implementing this?

Get a summary via Google for

$0

Get Help Now!

Tech Stack & Version

 Frontend

  • HTML5

 Backend

  • Laravel 8.x / 9.x / 10.x

  • PHP 7.4+

Deployment

  • Apache
  • Nginx
img

©2025Digittrix Infotech Private Limited , All rights reserved.