Panduan lengkap cara membuat fitur upload gambar, validasi ukuran file, dan konfigurasi storage link di Laravel 13.
Fitur upload file—seperti foto profil, dokumen PDF, atau gambar produk—adalah kebutuhan wajib di hampir setiap aplikasi web.
Di Laravel 13, pengelolaan file ditangani secara elegan melalui fitur Filesystem / Storage. Namun, banyak pengembang pemula mengalami masalah file berhasil di-upload tetapi gambar tidak muncul di browser (error 404).
Artikel ini akan membimbingmu membuat fitur upload file dari nol, melakukan validasi keamanan, serta mengonfigurasi Storage Link dengan benar.
1. Memahami Konsep Storage & Public Link
Secara default, file yang diunggah di Laravel disimpan secara terisolasi di folder storage/app/public agar aman dan tidak mudah diakses langsung dari luar.
Agar file tersebut bisa diakses oleh browser/publik, kita harus membuat Symbolic Link (Symlink) dari folder storage/app/public ke folder public/storage.
┌─────────────────────────────────────────────────────────────────────────┐
│ ALUR PENYIMPANAAN FILE LARAVEL │
├────────────────────────────────┬────────────────────────────────────────┤
│ Folder Asal (Terisolasi) │ Folder Akses Publik (Via Symlink) │
├────────────────────────────────┼────────────────────────────────────────┤
│ `storage/app/public/posts/` │ `public/storage/posts/` │
│ (Tempat file asli disimpan) │ (Shortcut akses browser) │
└────────────────────────────────┴────────────────────────────────────────┘
Jalankan perintah berikut di terminal kamu:
Bash
php artisan storage:link
Tips Hosting/Shared Hosting: Jika perintah di atas gagal di server hosting yang tidak menyediakan akses SSH, kamu bisa membuat route khusus sementara di
routes/web.phpuntuk menjalankanArtisan::call('storage:link').
2. Membuat Form Upload (Blade View)
Buat file view resources/views/upload.blade.php. Wajib tambahkan atribut enctype="multipart/form-data" pada tag <form> agar file dapat terkirim:
HTML
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Upload File - Laravel 13</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100 p-10">
<div class="max-w-md mx-auto bg-white p-6 rounded shadow">
<h2 class="text-xl font-bold mb-4">Upload Gambar Profil</h2>
@if (session('success'))
<div class="bg-green-100 text-green-700 p-3 rounded mb-4">
{{ session('success') }}
</div>
<img src="{{ asset('storage/' . session('path')) }}" class="w-32 h-32 object-cover rounded mb-4">
@endif
<form action="{{ route('upload.store') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="mb-4">
<input type="file" name="image" class="border w-full p-2 rounded">
@error('image')
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
@enderror
</div>
<button type="submit" class="bg-blue-600 text-white px-4 py-2 rounded">Upload Sekarang</button>
</form>
</div>
</body>
</html>
3. Menulis Logika Controller & Validasi
Buat controller baru menggunakan Artisan:
Bash
php artisan make:controller UploadController
Buka app/Http/Controllers/UploadController.php dan lengkapi logikanya:
PHP
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class UploadController extends Controller
{
public function index()
{
return view('upload');
}
public function store(Request $request)
{
// 1. Validasi Keamanan File
$request->validate([
'image' => 'required|image|mimes:jpeg,png,jpg,webp|max:2048', // Maksimal 2MB
]);
// 2. Simpan File ke Folder 'public/profiles'
if ($request->hasFile('image')) {
// Method store() otomatis mendaur ulang nama file menjadi unik (hash)
$path = $request->file('image')->store('profiles', 'public');
return back()->with([
'success' => 'Gambar berhasil diunggah!',
'path' => $path
]);
}
return back()->withErrors(['image' => 'Gagal mengunggah file.']);
}
}
4. Daftarkan Route Application
Buka file routes/web.php dan tambahkan route berikut:
PHP
use App\Http\Controllers\UploadController;
Route::get('/upload', [UploadController::class, 'index'])->name('upload.index');
Route::post('/upload', [UploadController::class, 'store'])->name('upload.store');
5. Cara Hapus File Lama dari Storage
Saat membuat fitur Edit Profile atau Update Post, jangan lupa menghapus file gambar lama agar tidak menumpuk di disk server:
PHP
use Illuminate\Support\Facades\Storage;
// Menghapus file gambar dari disk 'public'
if (Storage::disk('public')->exists($oldImagePath)) {
Storage::disk('public')->delete($oldImagePath);
}
Kesimpulan
Mengelola upload file di Laravel 13 terasa sangat mudah dan aman berkat adanya Storage abstraction layer. Selalu pastikan untuk menerapkan validasi ekstensi file (mimes) dan ukuran maksimal (max) untuk mencegah bahaya peretas memasukkan file skrip berbahaya (.php) ke dalam server kamu.
Selamat mencoba dan menguji fitur upload file di aplikasi Laravel 13 milikmu!
Ditulis oleh
Egi Samsul Mu'arif
Web & Mobile Developer



