Laravel provides a flexible and powerful file storage system, making it easy to store and retrieve files using different storage “disks.” Each disk represents a specific storage location and access type.
Types of Disks in Laravel
- Local Disk – Files are stored in storage/app. These are private by default and can’t be accessed directly via the browser.
- Public Disk – Files are saved under storage/app/public. These files are meant to be visible to the web.
- S3 Disk – Used for cloud storage via Amazon S3 (or other compatible services).
The key difference between these disks is accessibility files on the public disk are web-accessible through URLs, while local disk files stay private unless manually exposed through routes or controllers.
Method 1: Enable Public Access with Symbolic Links
By default, any image or file uploaded to the public disk is placed inside: storage/app/public.
However, these files are not automatically visible in your browser. To make them accessible, you need to create a symbolic link by running the following Artisan command:
php artisan storage:link
This command creates a shortcut between two folders:
- Actual file location: storage/app/public/
- Public shortcut path: public/storage/
When someone accesses /storage/images/photo.jpg, Laravel internally redirects the request to /storage/app/public/images/photo.jpg.
No files are duplicated the symbolic link simply connects the two directories.
Step 1: Upload Files to the Public Disk
When uploading files, specify that the file should be stored on the public disk. Below is a sample controller that handles image uploads and saves the file path to the database.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use App\Models\User;
class UserController extends Controller
{
public function store(Request $request)
{
$request->validate([ 'image' => 'required|mimes:jpg,png,jpeg',]);
// Saving an uploaded image
$imagePath = $request->file('image')->store('images','public');
//Save path to database
auth()->user()->update(['avatar'=>$imagePath]);
return back()->with('success','Image Uploaded Successfully!');
}
}
This method stores the uploaded image in storage/app/public/images and automatically links it through public/storage/images if the symbolic link exists.
Step 2: Display Images from Storage
Once your image is uploaded, you can display it in two simple ways either by retrieving the URL through the Storage Facade or using the asset() helper.
Option 1: Using Storage Facade in Controller
You can generate a valid public URL for a stored file using the Storage::url() method.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use App\Models\User;
class UserController extends Controller
{
public function displayImage()
{
$imageUrl = Storage::url('images/9FOxDeLj1oTMOuEpInT2sZSj4RsJQ0QNTFkboCcz.png');
return view('post',compact('imageUrl'));
}
}
Then, in your Blade file:
<img src="{{ asset($imageUrl) }}" alt="User Image" class="img-fluid mb-3">
- $imageUrl comes from the controller.
- asset() converts it to a full web URL (for example: https://yourapp.com/storage/images/sample-image.png).
Option 2: Directly Use Storage Facade in Blade
If you already know the filename, you can skip the controller variable and generate the URL directly in the Blade template:
<img src="{{ Storage::url('images/photo.jpg') }}" alt="Photo" class="img-fluid">
This approach is cleaner when displaying static or known files.
Option 3: Use Public Asset Path
If your files are already available under public/storage, you can reference them directly using the asset() helper:
<img src="{{ asset('storage/images/photo.png') }}" alt="Photo" class="img-fluid mb-3">
This method works because the asset('storage/...') path corresponds to files within your public/storage directory.
👉 Read full article here: Laravel 12 Display Image From Storage Folder


Top comments (0)