📧 Tutorial Sending Emails in Laravel with CID Images

In this tutorial, we'll learn how to send emails in Laravel with static images using **CID (Content-ID)**. With this method, images remain displayed even when the email recipient is offline.

Tags:
  • #Laravel
  • #Email
  • #CID Image
  • #PHP
  • #Mail
Learning Path: | Category: Laravel Tips

📌 Table of Contents

  1. Introduction
  2. Preparation
  3. Creating Email Helper
  4. Creating Email View with CID Image
  5. Using Helper to Send Email
  6. Conclusion

🔧 Preparation

  1. Ensure Laravel is installed.
  2. 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"
  3. 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:

  1. Detect <img> tags in the email using preg_replace_callback.
  2. Extract src from <img> tags to check if the image is from Laravel storage (/storage/...).
  3. Convert image path to absolute server path using storage_path().
  4. Embed the image in the email with $messageObj->embed() to encode as a CID Image.
  5. Replace image src in HTML with cid: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! 🎉

Logo Adib

© 2025 Adib

GitHub