Step 1: Install FilePond in Laravel Project
-
Install the FilePond JS library (frontend)
You can use npm or yarn:
npm install filepond filepond-plugin-image-preview filepond-plugin-file-validate-type filepond-plugin-file-validate-size
-
Include FilePond in your JS
In resources/js/app.js:
import * as FilePond from 'filepond';
import 'filepond/dist/filepond.min.css';
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.css';
import FilePondPluginImagePreview from 'filepond-plugin-image-preview';
import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type';
import FilePondPluginFileValidateSize from 'filepond-plugin-file-validate-size';
FilePond.registerPlugin(
FilePondPluginImagePreview,
FilePondPluginFileValidateType,
FilePondPluginFileValidateSize
);
-
Compile assets
npm run dev
Step 2: Create the Migration and Model
Assume we have a products table and we want to save images.
php artisan make:model Product -m
In migration:
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('images')->nullable(); // Store image paths as JSON
$table->timestamps();
});
php artisan migrate
In Product.php:
class Product extends Model
{
protected $fillable = ['name', 'images'];protected $casts = [
'images' => 'array', // Automatically casts JSON to array
];
}
Step 3: Create Controller
php artisan make:controller ProductController
In ProductController.php:
use App\Models\Product;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class ProductController extends Controller
{
// Show form
public function create()
{
return view('products.create');
}
// Store product with images
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'images.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
$images = [];
if($request->hasFile('images')) {
foreach($request->file('images') as $image){
$path = $image->store('products', 'public');
$images[] = $path;
}
}
Product::create([
'name' => $request->name,
'images' => $images,
]);
return redirect()->back()->with('success', 'Product added successfully!');
}
// Show edit form
public function edit(Product $product)
{
return view('products.edit', compact('product'));
}
// Update product and images
public function update(Request $request, Product $product)
{
$request->validate([
'name' => 'required|string|max:255',
'images.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
$images = $product->images ?? [];
if($request->hasFile('images')) {
// Optionally delete old images
foreach($images as $img){
Storage::disk('public')->delete($img);
}
$images = [];
foreach($request->file('images') as $image){
$path = $image->store('products', 'public');
$images[] = $path;
}
}
$product->update([
'name' => $request->name,
'images' => $images,
]);
return redirect()->back()->with('success', 'Product updated successfully!');
}
}
Step 4: Create Blade Views
create.blade.php
<form action="{{ route('products.store') }}" method="POST" enctype="multipart/form-data">
@csrf
<input type="text" name="name" placeholder="Product Name" required><input type="file" name="images[]" multiple id="filepond">
<button type="submit">Save</button>
</form>
<script src="https://unpkg.com/filepond/dist/filepond.js"></script>
<script>
const inputElement = document.querySelector('input[id="filepond"]');
FilePond.create(inputElement, {
allowMultiple: true,
maxFiles: 5,
acceptedFileTypes: ['image/*'],
});
</script>
edit.blade.php
<form action="{{ route('products.update', $product->id) }}" method="POST" enctype="multipart/form-data">
@csrf
@method('PUT')
<input type="text" name="name" value="{{ $product->name }}" required><input type="file" name="images[]" multiple id="filepond">
<button type="submit">Update</button>
</form>
<script src="https://unpkg.com/filepond/dist/filepond.js"></script>
<script>
const inputElement = document.querySelector('input[id="filepond"]');
FilePond.create(inputElement, {
allowMultiple: true,
maxFiles: 5,
acceptedFileTypes: ['image/*'],
files: [
@foreach($product->images as $img)
{
source: "{{ asset('storage/'.$img) }}",
options: { type: 'local' }
},
@endforeach
]
});
</script>
Step 5: Add Routes
use App\Http\Controllers\ProductController;
Route::get('products/create', [ProductController::class, 'create'])->name('products.create');
Route::post('products/store', [ProductController::class, 'store'])->name('products.store');
Route::get('products/{product}/edit', [ProductController::class, 'edit'])->name('products.edit');
Route::put('products/{product}/update', [ProductController::class, 'update'])->name('products.update');
Step 6: Test
- Visit /products/create → Upload images → Submit.
- Visit /products/{id}/edit → See previously uploaded images → Replace or add new images → Update.
