Setting Up Continuous Integration for Laravel Packages
Laravel package maintainers need tests that check how their code behaves inside Laravel, across the PHP and Laravel versions the package supports.…
A Laravel mailable gets its email body and attachments from separate parts of its configuration. An HTML or plain-text view supplies the body. A regular attachment is a file the recipient can open or download; an inline image appears at a chosen place in the HTML body.
In Laravel 13, add regular files through the mailable’s attachments() method. To show an image in the message, call $message->embed() in the HTML template and put the result in the image’s src attribute. Laravel sends the inline image as a separate part of the email. The HTML refers to that part by its Content-ID, or CID, an identifier for the image. These examples use Laravel’s current Content and Attachment pattern. If your project uses an older Laravel release, check that version’s documentation.
Have attachments() return an Attachment to include a regular file attachment. Laravel can attach a file from a path or filesystem disk, or content held in memory. The Laravel mail documentation describes these options.
invoicePath)
->as('invoice.pdf')
->withMime('application/pdf'),
];
}
}
fromPath() reads a file available at the supplied path. Use as() to set the filename the recipient sees and withMime() to specify the file’s media type, such as application/pdf. For files stored on Laravel’s configured default disk, use Attachment::fromStorage($path); to choose a named disk, use Attachment::fromStorageDisk($disk, $path). For generated content that already exists in memory, use Attachment::fromData(fn () => $bytes, 'report.pdf').
The content() method selects the views that render the email body; it does not add a file attachment. A mailable that only selects views sends the rendered body without a separate file unless attachments() returns one.
Call $message->embed() in the HTML template and put the returned value in the image’s src attribute. Laravel prepares the image for inline use and gives the HTML a reference to it.
Your invoice is attached.
<img>embed(public_path('images/company-logo.png')) }}"
alt="Company logo"
>
If the image bytes are already in memory, use $message->embedData($data, 'image.jpg'). Both methods add an inline image. A regular Attachment makes a file available to the recipient as an attachment; it does not place the file at a specific spot in the HTML. Symfony’s Mailer documentation on embedded images explains that the HTML refers to an inline image by its CID.
Laravel provides $message in HTML email templates, but not in plain-text templates, which cannot display inline images. Put the image in the HTML view and give the text view an equivalent description or message:
Your invoice is attached. The email includes the company logo.
The mailable sends both versions in the example. Its HTML view displays the logo, while its text view gives the message without the image. The attachments() method adds the invoice PDF.
Laravel’s current documentation explains how to embed images in email templates, but it does not confirm that every template type, mail transport, and recipient’s email client behaves the same way. A historical Laravel issue about Markdown mailables reported an embedding problem on Laravel 10.10.1. That report does not show whether the same problem affects current releases. If a Markdown mailable needs an inline image, test it with the Laravel version and mail transport your project uses.
Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.
Take a look at vroni.com