How to attach image from storage in mail Laravel
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
How to Attach Images from Storage in Mail in Laravel: A Complete Guide
As a senior developer working with the Laravel ecosystem, dealing with file attachments in emails is a very common requirement. You have your files sitting safely in your storage system (like the storage/app/proof directory), but getting them into an email requires understanding how Laravel's Mail system handles MIME attachments. If you are running into issues attaching images, it’s usually not about the file path itself, but rather how you instruct the Mail facade to handle that file stream.
This guide will walk you through the correct, robust way to attach files stored on your disk to an outgoing email in Laravel, ensuring your images arrive perfectly attached.
Understanding the Pitfall: Why Direct Pathing Fails
When you try to attach a file directly by referencing a path (e.g., $user->proofLink = request()->file('proofFile')->store('proof');), you are primarily dealing with saving or moving files on the filesystem. While this confirms the file exists, it doesn't automatically instruct the Mail system how to read that file and format it as a proper MIME attachment for delivery.
To successfully attach a file, you need to use Laravel’s built-in file handling mechanisms—specifically the Illuminate\Support\Facades\Storage facade—to retrieve the file content or stream.
The Correct Approach: Using the Storage Facade
The most reliable method involves using the Storage facade to access the file and then passing that data correctly to the Mail::attach() method. This ensures that Laravel handles the necessary encoding and MIME type headers required by email clients.
Step 1: Ensure File is Stored Correctly
First, let's assume you have successfully stored your image in a disk (like public or s3) using the Storage facade.
use Illuminate\Support\Facades\Storage;
// Example: Storing an image to the 'proof' directory on the local disk
$path = 'proof/' . $filename;
Storage::disk('public')->put($path, $imageContent);
Step 2: Attaching the File in Your Mail Class
Inside your Mailable class (e.g., ConfirmAccount.php), you will access the file using the stored path and attach it. For files stored on local disks, we use the Storage facade again within the mailer context.
Here is an example of how you would structure your Mailable to attach a file:
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use Illuminate\Mail\Mailable;
class ConfirmAccount extends Mailable
{
public $user;
public function __construct($user)
{
$this->user = $user;
}
public function build()
{
// Assume the image file name is stored in the database, e.g., $this->user->image_name
$imageFileName = 'proof/my_document.jpg'; // Path relative to your disk configuration
// 1. Retrieve the file content stream from storage
$fileContents = Storage::disk('public')->get($imageFileName);
// 2. Attach the file using Mail::attach()
Mail::attach(
$imageFileName, // The path/filename as seen by the storage system
$fileContents // The actual binary content of the file
);
return $this->view('emails.confirm_account');
}
}
Note on Laravel Best Practices: When dealing with large files or cloud storage, especially when scaling your application, leveraging services like Amazon S3 (which Laravel integrates seamlessly via packages) is highly recommended. This approach aligns perfectly with modern architectural patterns discussed in resources like those provided by laravelcompany.com.
Summary and Conclusion
The issue you encountered likely stemmed from confusing file system operations (saving the file) with mail delivery operations (attaching the file stream). By correctly utilizing the Storage facade to retrieve the raw binary content of the file and passing that content along with the filename to Mail::attach(), you ensure that Laravel properly formats the data into a valid MIME attachment for your recipient.
Always remember to check your disk configuration (config/filesystems.php) to ensure that the disk you are using (local, public, s3, etc.) is correctly configured and accessible by your application. Mastering these file I/O operations is key to building robust applications with Laravel.