📂 Laravel 12 File Upload to Storage Folder Example

Uploading files is a common task in many web applications. Laravel 12 makes it incredibly simple with its built-in storage system. In this post, we'll learn how to upload and store a file (like an image or document) using Laravel 12 and display it on the frontend.


✅ What You’ll Learn

  • Laravel 12 project setup
  • Configure storage folder and symbolic link
  • Create model, migration, controller
  • Upload files to storage/app/public
  • Display uploaded files


🧰 Step 1: Install Laravel 12 Project

If you haven’t already installed Laravel 12:

composer create-project laravel/laravel laravel12-file-upload
cd laravel12-file-upload

Start the development server:

php artisan serve

⚙️ Step 2: Configure Storage Disk

Laravel uses the filesystems.php config file to define where files are stored.

Open config/filesystems.php and ensure the public disk is defined like this:

'disks' => [
// ...
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL') . '/storage',
'visibility' => 'public',
],
],

Now create the symbolic link from public/storage to storage/app/public:

php artisan storage:link

This allows access to uploaded files via the browser.


🗃️ Step 3: Create Model and Migration

We’ll create a model named File to store file info in the database.

php artisan make:model File -m

Open the generated migration file in database/migrations/ and update it:

public function up()
{
Schema::create('files', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('path');
$table->timestamps();
});
}

Run the migration:

php artisan migrate

🧭 Step 4: Create Routes

Open routes/web.php and add the following routes:

use App\Http\Controllers\FileController;
Route::get('/file/create', [FileController::class, 'create'])->name('file.create');
Route::post('/file/store', [FileController::class, 'store'])->name('file.store');
Route::get('/file/{id}', [FileController::class, 'show'])->name('file.show');

🧑‍💻 Step 5: Create Controller

Generate a controller:

php artisan make:controller FileController

Then update the app/Http/Controllers/FileController.php with:

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\File;
class FileController extends Controller
{
public function create()
{
return view('file.create');
}
public function store(Request $request)
{
$request->validate([
'file' => 'required|file|mimes:jpg,png,jpeg,pdf|max:2048',
]);
$uploadedFile = $request->file('file');
$filePath = $uploadedFile->store('uploads', 'public');
$file = new File();
$file->name = $uploadedFile->getClientOriginalName();
$file->path = $filePath;
$file->save();
return redirect()->route('file.show', $file->id)
->with('success', 'File uploaded successfully!');
}
public function show($id)
{
$file = File::findOrFail($id);
return view('file.show', compact('file'));
}
}

🧾 Step 6: Create Blade Views

1. resources/views/file/create.blade.php

<!DOCTYPE html>
<html>
<head>
<title>Laravel 12 File Upload</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<h2>Upload File</h2>
@if ($errors->any())
<div class="alert alert-danger">
<ul>@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach</ul>
</div>
@endif
<form action="{{ route('file.store') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="mb-3">
<label>Select File:</label>
<input type="file" name="file" class="form-control">
</div>
<button class="btn btn-primary" type="submit">Upload</button>
</form>
</div>
</body>
</html>

2. resources/views/file/show.blade.php

<!DOCTYPE html>
<html>
<head>
<title>File Preview</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<h2>Uploaded File Preview</h2>
<p><strong>File Name:</strong> {{ $file->name }}</p>
<p><strong>File Path:</strong> {{ $file->path }}</p>
@if (in_array(pathinfo($file->path, PATHINFO_EXTENSION), ['jpg', 'jpeg', 'png']))
<img src="{{ asset('storage/' . $file->path) }}" class="img-fluid" alt="{{ $file->name }}">
@else
<a href="{{ asset('storage/' . $file->path) }}" class="btn btn-info" target="_blank">Download File</a>
@endif
<br><br>
<a href="{{ route('file.create') }}" class="btn btn-secondary">Upload Another</a>
</div>
</body>
</html>

🧪 Step 7: Test the Application

Run the Laravel server if not already:

php artisan serve

Visit:

🔗 http://localhost:8000/file/create

  • Select an image or PDF to upload
  • On success, you'll be redirected to a preview page


📌 Notes & Best Practices

  • Uploaded files are stored in: storage/app/public/uploads/
  • Accessible publicly via: public/storage/uploads/...
  • You can customize file storage disk and path based on needs
  • Always validate file type and size for security


✅ Conclusion

You’ve successfully built a file upload system in Laravel 12 that:

  • Validates the file

  • Uploads it to the storage folder

  • Saves file info to database

  • Displays the uploaded file

Post a Comment

Previous Post Next Post

Contact Form