Kritim Yantra
Mar 28, 2025
Handling image uploads and displaying them in a web application is a common requirement for many projects. Laravel, a powerful PHP framework, and ReactJS, a popular JavaScript library, together provide an excellent full-stack solution for this task. Laravel excels at managing server-side logic and file storage, while ReactJS is perfect for creating dynamic, interactive user interfaces.
In this detailed blog post, we’ll walk through the process of setting up a full-stack application to upload and display images using Laravel 12 as the backend and ReactJS as the frontend.
By the end of this guide, you’ll have a fully functional application where users can upload images to a Laravel backend and see them displayed in a ReactJS frontend.
Before diving into the implementation, let’s briefly understand the tools we’ll be using:
When combined, Laravel serves as the API backend to handle image uploads and storage, while ReactJS provides a responsive and dynamic frontend to interact with the user.
Laravel is installed using Composer, a PHP dependency manager. Open your terminal and run:
composer create-project laravel/laravel laravel-react-image-upload
Navigate into the project folder:
cd laravel-react-image-upload
Install React scaffolding with:
composer require laravel/ui
php artisan ui react
npm install
Laravel 12 uses Vite for asset compilation:
npm run build
Run the following command to create a model and migration:
php artisan make:model Image -m
Modify the migration file in database/migrations
:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('images', function (Blueprint $table) {
$table->id();
$table->string('path');
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('images');
}
};
Run the migration:
php artisan migrate
Create a symbolic link to make stored files publicly accessible:
php artisan storage:link
Run:
php artisan make:controller ImageController
Modify app/Http/Controllers/ImageController.php
:
namespace App\Http\Controllers;
use App\Models\Image;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class ImageController extends Controller
{
public function index()
{
return Image::all();
}
public function store(Request $request)
{
$request->validate([
'image' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
]);
$path = $request->file('image')->store('images', 'public');
$image = Image::create(['path' => $path]);
return response()->json($image, 201);
}
}
Install API
php artisan install:api
Modify routes/api.php
:
use App\Http\Controllers\ImageController;
use Illuminate\Support\Facades\Route;
Route::get('/images', [ImageController::class, 'index']);
Route::post('/images', [ImageController::class, 'store']);
npm install axios
Create resources/js/components/ImageUpload.js
:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const ImageUpload = () => {
const [images, setImages] = useState([]);
const [file, setFile] = useState(null);
useEffect(() => {
fetchImages();
}, []);
const fetchImages = async () => {
const response = await axios.get('/api/images');
setImages(response.data);
};
const handleFileChange = (e) => {
setFile(e.target.files[0]);
};
const handleUpload = async () => {
if (!file) return;
const formData = new FormData();
formData.append('image', file);
const response = await axios.post('/api/images', formData, {
headers: { 'Content-Type': 'multipart/form-data' }
});
setImages([...images, response.data]);
setFile(null);
};
return (
<div>
<h1>Image Upload</h1>
<input type="file" onChange={handleFileChange} />
<button onClick={handleUpload}>Upload</button>
<div>
{images.map(image => (
<img key={image.id} src={`/storage/${image.path}`} alt="Uploaded" width="200" />
))}
</div>
</div>
);
};
export default ImageUpload;
Modify resources/js/app.js
:
import { createRoot } from 'react-dom/client';
import ImageUpload from './components/ImageUpload';
const root = createRoot(document.getElementById('app'));
root.render(<ImageUpload />);
Modify resources/views/welcome.blade.php
:
<!DOCTYPE html>
<html>
<head>
<title>Laravel & React</title>
@vite('resources/js/app.js')
</head>
<body>
<div id="app"></div>
</body>
</html>
composer run dev
This tutorial covered the complete process of setting up Laravel and ReactJS to handle image uploads and display them dynamically. This approach keeps backend logic separate from frontend UI, resulting in a scalable and maintainable application.
No comments yet. Be the first to comment!
Please log in to post a comment:
Continue with Google