📌 Table of Contents
- Introduction
- Preparation
- Creating Email Helper
- Creating Email View with CID Image
- Using Helper to Send Email
- Conclusion
🔧 Preparation
- Ensure Laravel is installed.
- Configure SMTP in
.env
:MAIL_MAILER=smtp MAIL_HOST=smtp.example.com MAIL_PORT=587 MAIL_USERNAME=your_email@example.com MAIL_PASSWORD=your_password MAIL_ENCRYPTION=tls MAIL_FROM_ADDRESS=your_email@example.com MAIL_FROM_NAME="Your Name"
- Run
php artisan storage:link
to access images from storage.
📌 Creating Email Helper
Create app/Helpers/EmailHelper.php
:
<?php
namespace App\Helpers;
use Illuminate\Support\Facades\Mail;
use Exception;
class EmailHelper
{
public static function sendEmail($to, $subject, $message, $attachments = [], $cc = [], $bcc = [])
{
try {
Mail::send([], [], function ($messageObj) use ($to, $subject, $message, $attachments, $cc, $bcc) {
$messageWithInlineImages = self::processInlineImages($message, $messageObj);
$messageObj->to($to)
->subject($subject)
->html($messageWithInlineImages);
if (!empty($cc)) $messageObj->cc($cc);
if (!empty($bcc)) $messageObj->bcc($bcc);
if (!empty($attachments)) {
foreach ($attachments as $attachment) {
$messageObj->attach($attachment);
}
}
});
return true;
} catch (Exception $e) {
logger("EmailHelper: " . $e->getMessage());
throw new Exception("Failed to send email: " . $e->getMessage());
}
}
private static function processInlineImages($body, $messageObj)
{
return preg_replace_callback('/<img[^>]+src=["\'](.*?)["\']/i', function ($matches) use ($messageObj) {
$imagePath = $matches[1];
if (strpos($imagePath, '/storage') === 0) {
$filePath = storage_path('app/public' . parse_url($imagePath, PHP_URL_PATH));
if (file_exists($filePath)) {
$cid = 'cid_' . uniqid();
$messageObj->embed($filePath, ['content-id' => $cid]);
return 'src="cid:' . $cid . '"';
}
}
return $matches[0];
}, $body);
}
}
🖼 Creating Email View with CID Image
Create resources/views/emails/sample.blade.php
:
<!DOCTYPE html>
<html>
<head>
<title>Email with CID Image</title>
</head>
<body>
<h2>Hello, this is an email with a CID image</h2>
<p>Here's an inline image:</p>
<img src="/storage/email/logo.png" alt="Logo">
</body>
</html>
Ensure the image is stored at storage/app/public/email/logo.png
🔍 Understanding processInlineImages
The processInlineImages
function is responsible for converting images from local paths (/storage/...
) to Content-ID (CID) to be included as inline attachments in emails.
How It Works:
- Detect
<img>
tags in the email usingpreg_replace_callback
. - Extract
src
from<img>
tags to check if the image is from Laravel storage (/storage/...
). - Convert image path to absolute server path using
storage_path()
. - Embed the image in the email with
$messageObj->embed()
to encode as a CID Image. - Replace image
src
in HTML withcid:unique_id
, so the image displays from the email, not from an external URL.
HTML Email Transformation Example:
Before:
<img src="/storage/email/logo.png" alt="Logo">
After:
<img src="cid:cid_123456789" alt="Logo">
With this method, images remain displayed even when the email recipient is offline.
📤 Using Helper to Send Email
In a controller or service, use the following code to send an email:
use App\Helpers\EmailHelper;
EmailHelper::sendEmail(
'recipient@example.com',
'Email Subject',
view('emails.sample')->render()
);
✅ Conclusion
With this method, images in emails remain displayed even when the recipient is offline. This is useful for sending emails with branding or important images without relying on external sources.
Happy coding! 🎉