eduardokum/laravel-mail-auto-embed
Laravel package that automatically embeds images in outgoing mailables, turning remote or local image URLs into inline CID attachments so they render reliably in every email client—no manual attachment wiring or template changes required.
composer require eduardokum/laravel-mail-auto-embed. The service provider is auto-discovered on Laravel 5.5+; on older versions register Eduardokum\LaravelMailAutoEmbed\ServiceProvider in config/app.php.php artisan vendor:publish --provider="Eduardokum\LaravelMailAutoEmbed\ServiceProvider" to get config/mail-auto-embed.php. Defaults are usually fine — the key knobs are enabled, embedder (attachment vs base64), disc, and http_client.options.vendor/eduardokum/laravel-mail-auto-embed/src/Embedder/ to see the two built-in strategies, and at Contracts/Embedder.php / EmbeddedImage.php if you plan to customize how images are resolved.<img src="{{ asset('img/logo.png') }}"> or <img src="https://cdn.example.com/hero.png"> and send the mail as usual. The package rewrites every <img src> to a CID reference and attaches the underlying file before the message leaves Laravel's mailer — no ->with() image plumbing, no manual $message->embed().<img src> in Blade and Markdown mailables. The package handles the transformation at send time, so your Mailable classes stay free of image code.disc to a configured filesystem (usually public) and reference paths relative to that disk. If you rely on asset() URLs for local files, make sure php artisan storage:link has been run and the URL maps back to the disk the package is configured to search.http(s):// URLs are fetched at send time and embedded. Good for CDN-hosted logos and hero images; watch timeouts (see Gotchas).attachment (default) produces CID parts, keeps HTML compact, and works well across clients — the right default for marketing/transactional mail. base64 produces self-contained HTML that survives clients which strip CID, but inflates size significantly — reserve it for small, critical images.MailMessage notifications and ShouldQueue mailables still flow through the same mailer, so embedding applies. The fetch/read happens on the worker at send time — keep image endpoints fast and cacheable.Eduardokum\LaravelMailAutoEmbed\Contracts\Embedder (the fromUrl / fromPath methods returning an EmbeddedImage) and point embedder in config at your class when you need signed URLs, an internal CDN, or pre-storage of images.MAIL_AUTO_EMBED=false locally or in tests when you want to see the raw template output (broken images and all) during debugging.<img src> is rewritten. CSS background-image, <image href> in inline SVG, and URLs inside <style> blocks are not embedded. Convert critical art to <img> or you'll ship broken emails.attachment for anything bigger than a small logo.http_client.options.timeout, be deliberate about verify (avoid disabling it for public mail), and log fetch failures.Mail::fake() / Notification::fake() skip embedding. With fake transports the message is never built, so your assertions see the original src, not the transformed one. Use Mailpit/Mailhog or a real transport when you need to verify CID parts and Content-Disposition.$message->embed() / $message->embedData() for an image, the package will embed it again and produce duplicate attachments. Let the package own <img> handling.disc. For local files, use paths relative to the configured disk (or a URL you can reliably map back); full-URL paths will hit the HTTP client instead.src as untrusted. User-supplied image URLs can cause SSRF against internal hosts. Only enable embedding for templates you control, or constrain/allowlist origins in a custom embedder.multipart/related with CID parts and the expected filenames. Check storage/logs/laravel.log for HTTP client errors if images are missing.mail-auto-embed.php, run php artisan config:clear locally and config:cache in production, or your changes silently won't apply.How can I help you explore Laravel packages today?