Install Dependencies:
composer require twig/twig symfony/dom-crawler spatie/laravel-swiftmailer
twig/twig: For templating.symfony/dom-crawler: Required for inline image handling.spatie/laravel-swiftmailer: To integrate SwiftMailer with Laravel.Configure SwiftMailer: Publish and configure SwiftMailer settings:
php artisan vendor:publish --provider="Spatie\SwiftMailer\SwiftMailerServiceProvider"
Update .env with your mail configuration (e.g., SMTP settings).
Set Up Twig:
Register Twig in config/app.php under providers:
Twig\Extension\CoreExtension::class,
Twig\Extension\DebugExtension::class,
Configure Twig in config/services.php:
'twig' => [
'paths' => [
resource_path('views/emails'),
],
],
Create a Twig Email Template:
Save a template at resources/views/emails/welcome.mail.twig:
{% block subject %}
Welcome to Our Platform, {{ user.name }}!
{% endblock %}
{% block body_text %}
Hello {{ user.name }},
Thank you for signing up!
{% endblock %}
{% block body_html %}
<h1>Hello {{ user.name }},</h1>
<p>Thank you for signing up!</p>
<img src="/images/logo.png" class="inline-image" alt="Logo">
{% endblock %}
Send the First Email: In a controller or service:
use WMC\SwiftmailerTwigBundle\TwigSwiftHelper;
use Swift_Message;
public function sendWelcomeEmail()
{
$twig = app('twig');
$webDir = public_path();
$helper = new TwigSwiftHelper($twig, $webDir);
$message = (new Swift_Message())
->setTo('user@example.com')
->setFrom('noreply@example.com');
$data = ['user' => ['name' => 'John Doe']];
$helper->populateMessage($message, 'emails/welcome.mail.twig', $data);
app('swiftmailer')->send($message);
}
resources/views/emails/ with .mail.twig extension.user_activation.mail.twig, password_reset.mail.twig).resources/views/emails/notifications/).$data = [
'user' => ['name' => 'Jane Doe', 'email' => 'jane@example.com'],
'reset_link' => 'https://example.com/reset-password?token=123',
];
{% block subject %}
Reset Your Password, {{ user.name }}
{% endblock %}
{# resources/views/emails/_layout.mail.twig #}
{% block header %}
<h1>Our Company</h1>
{% endblock %}
{% block content %}
{{ include('emails/' ~ template_name ~ '.mail.twig') }}
{% endblock %}
{% block footer %}
<p>© 2023 Our Company</p>
{% endblock %}
{% extends 'emails/_layout.mail.twig' %}
{% block content %}
<p>Hello {{ user.name }},</p>
{% endblock %}
class="inline-image" to <img> tags with absolute paths (starting with /):
<img src="/images/logo.png" class="inline-image" alt="Logo">
public/images/).body_text block for compatibility with email clients that strip HTML:
{% block body_text %}
Hello {{ user.name }},
Please click the link below to reset your password:
{{ reset_link }}
Best regards,
The Team
{% endblock %}
Mail facade to preview emails locally:
use Illuminate\Support\Facades\Mail;
Mail::raw('Test email body', function ($message) {
$message->to('test@example.com')
->subject('Test Subject');
});
public function renderEmailTemplate(string $template, array $data): string
{
$twig = app('twig');
return $twig->render("emails/{$template}", $data);
}
Create/Edit Templates:
resources/views/emails/.Send Test Emails:
docker run -d -p 1025:1025 -p 8025:8025 mailhog/mailhog
.env:
MAIL_MAILER=smtp
MAIL_HOST=localhost
MAIL_PORT=1025
Debugging:
http://localhost:8025 for rendered emails.$twig->enableDebug(); // In development only!
Version Control:
README.md in the resources/views/emails/ directory.Template Updates:
Environment-Specific Data:
$data = array_merge($data, [
'brand_color' => config('mail.brand_color'),
'support_email' => config('mail.support_email'),
]);
Caching:
$twig->setCache(false);
Mail facade with SwiftMailer/Twig:
use Illuminate\Mail\Mailable;
use WMC\SwiftmailerTwigBundle\TwigSwiftHelper;
class TwigMailable extends Mailable
{
public function build()
{
$helper = new TwigSwiftHelper(app('twig'), public_path());
$message = (new Swift_Message())
->setTo($this->recipient)
->setFrom(config('mail.from.address'));
$helper->populateMessage($message, $this->template, $this->data);
return $message;
}
}
Mail::to('user@example.com')->send(new TwigMailable('emails/welcome.mail.twig', $data));
Mail::to('user@example.com')->queue(new TwigMailable('emails/welcome.mail.twig', $data));
php artisan queue:work
{% block subject %}
{{ 'welcome.subject'|trans(['name' => user.name]) }}
{% endblock %}
resources/lang/{locale}/emails.php:
return [
'welcome.subject' => 'Welcome, :name!',
];
populateMessage call:
$message->attach($filePath, [
'as' => '
How can I help you explore Laravel packages today?