Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Mailer Bundle Laravel Package

sylius/mailer-bundle

SyliusMailerBundle integrates the Sylius Mailer component with Symfony, providing configurable email sending, templating, and sender management for Sylius eCommerce applications. It simplifies transactional email setup and customization.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require sylius/mailer-bundle:^2.2.1
    

    Add the bundle to config/bundles.php:

    return [
        // ...
        Sylius\Bundle\MailerBundle\SyliusMailerBundle::class => ['all' => true],
    ];
    

    Version note: v2.2.1 is a drop-in patch over v2.2.0 (no BC breaks) but it fixes the EmailTwigAdapter against Twig 3.29's TemplateWrapper::unwrap() signature change. If your project resolves Twig ^3.29, pin sylius/mailer-bundle:^2.2.1 — older patches will fatal when rendering a mail template.

  2. Configuration Configure your mailer in config/packages/sylius_mailer.yaml:

    sylius_mailer:
        mailer:
            dsn: '%env(MAILER_DSN)%' # e.g., 'smtp://user:[email protected]:port'
            transport: 'smtp' # or 'sendmail', 'failover', etc.
        templates:
            path: '%kernel.project_dir%/templates/mailer'
    
  3. Sanity-check the wiring before writing any email code

    php bin/console debug:container sylius.mailer.sender
    php bin/console debug:config sylius_mailer
    composer show sylius/mailer-bundle twig/twig
    

    If the container compiles and the Twig version is sane, the adapter is fine.

  4. First Use Case Create a template file (e.g., welcome.txt.twig in templates/mailer/):

    Hello {{ name }},
    
    Welcome to our platform!
    

    Send an email in a controller:

    use Sylius\Component\Mailer\Sender\SenderInterface;
    
    public function sendWelcomeEmail(SenderInterface $sender, string $email, string $name): void
    {
        $sender->send(
            new Email(
                'Welcome',
                $email,
                'welcome.txt.twig',
                ['name' => $name]
            )
        );
    }
    

Implementation Patterns

Core Workflows

  1. Template Management

    • Store templates in templates/mailer/ (supports .twig, .html.twig, .txt.twig).
    • Use Twig variables for dynamic content:
      {# templates/mailer/order_confirmation.html.twig #}
      <h1>Order #{{ order.number }}</h1>
      
    • Override default templates by placing them in your project's templates/mailer/ directory.
    • Keep template syntax to constructs that are stable across Twig minors (see Gotchas on the adapter) — avoid calling internal Twig APIs from templates or extensions.
  2. Email Sending

    • Basic Send:
      $sender->send(new Email('Subject', '[email protected]', 'template.twig', ['var' => 'value']));
      
    • Async Sending (via Symfony Messenger):
      # config/packages/messenger.yaml
      framework:
          messenger:
              transports:
                  async: '%env(MESSENGER_TRANSPORT_DSN)%'
              routing:
                  'Sylius\Component\Mailer\Message\SendEmailMessage': async
      
      Then dispatch:
      $bus->dispatch(new SendEmailMessage($email));
      
  3. Event-Driven Emails Subscribe to Sylius events (e.g., OrderCreatedEvent) and trigger emails:

    use Sylius\Component\Core\Event\OrderCreatedEvent;
    
    public function __invoke(OrderCreatedEvent $event): void
    {
        $sender->send(new Email(
            'Order Confirmation',
            $event->getOrder()->getCustomer()->getEmail(),
            'order_confirmation.html.twig',
            ['order' => $event->getOrder()]
        ));
    }
    
  4. Testing

    • Use a null transport for tests:
      sylius_mailer:
          mailer:
              transport: 'null://default'
      
    • Assert on the Symfony mailer event/log, or bind a spy decorator around SenderInterface and assert calls on it (more robust than relying on bundle internals).
    • Add a smoke test that actually renders each template through the adapter:
      $this->assertNotEmpty($twig->render('@SyliusMailer/.../welcome.html.twig', ['name' => 'x']));
      
      This is exactly the class of bug v2.2.1 fixed, and a render smoke test catches it on the next Twig bump.

Integration Tips

  • Keep Twig and the bundle in lockstep: bump them together in CI. A Twig minor can change adapter internals without any deprecation, so treat twig/twig as a coupled dependency.

  • Custom Mailer Logic: Extend the Email class or create a decorator for SenderInterface:

    class CustomSender implements SenderInterface
    {
        private $decorated;
    
        public function __construct(SenderInterface $decorated) { $this->decorated = $decorated; }
    
        public function send(Email $email): void
        {
            // Add custom logic (e.g., logging, analytics)
            $this->decorated->send($email);
        }
    }
    

    Register as a service:

    services:
        Sylius\Component\Mailer\Sender\SenderInterface: '@app.custom_sender'
    

    A decorator is also the cleanest place to swap in a test double.

  • Dynamic Templates: Use a service to resolve template paths dynamically:

    $templatePath = $this->templateResolver->resolve('mailer', 'dynamic_template.twig', ['locale' => $locale]);
    
  • Localization: Combine with Symfony's translation system for multi-language emails:

    {# templates/mailer/welcome.html.twig #}
    <h1>{{ 'welcome.heading'|trans }}</h1>
    

Gotchas and Tips

Pitfalls

  1. Twig 3.29+ and EmailTwigAdapter (fixed in v2.2.1)

    • Twig 3.29 changed the signature of TemplateWrapper::unwrap(). Bundles before v2.2.1 call it the old way and blow up at render time — typically a TypeError/ArgumentCountError surfaced the moment a mail template is rendered, not at container compile time.
    • Remedy: composer require sylius/mailer-bundle:^2.2.1. If your lockfile pins an older patch, composer update sylius/mailer-bundle is enough — it's a patch bump with no API changes.
    • The failure mode is nasty because it only triggers when an email is actually rendered (queued async mail can fail long after deploy). Add the render smoke test above so this class of break shows up in CI.
  2. Template Caching:

    • Twig templates are cached by default. Clear cache after changes:
      php bin/console cache:clear
      
    • Disable caching in config/packages/twig.yaml for development:
      twig:
          cache: false
      
  3. DSN Configuration:

    • Ensure MAILER_DSN is correctly formatted (e.g., smtp://user:pass@host:port).
    • For Gmail, use:
      sylius_mailer:
          mailer:
              dsn: '%env(MAILER_DSN)%'
              transport_options:
                  encryption: ssl
                  port: 465
      
  4. Async Transport Quirks:

    • If using async transport, ensure the messenger worker is running:
      php bin/console messenger:consume async -vv
      
    • Debug failed messages with:
      php bin/console messenger:failed:list
      php bin/console messenger:failed:retry <message-id>
      
    • After upgrading Twig, drain/retry failed messages — queued jobs serialized before the upgrade may replay through the old code path.
  5. Attachment Limits:

    • Large attachments may fail silently. Validate file sizes before sending:
      if ($attachment->getSize() > 10_000_000) { // 10MB
          throw new \RuntimeException('Attachment too large');
      }
      

Debugging

  • Log Sent Emails: Add a subscriber to log emails:

    public function onEmailSent(EmailSentEvent $event): void
    {
        $this->logger->info('Email sent', [
            'subject' => $event->getEmail()->getSubject(),
            'to' => $event->getEmail()->getTo(),
        ]);
    }
    
  • Check Transport Errors: Enable verbose logging in config/packages/monolog.yaml:

    monolog:
        handlers:
            main:
                level: debug
    
  • Isolate render vs. transport failures: render the template yourself first ($twig->render(...)), then send. Adapter/Twig problems look identical to transport problems in logs otherwise.

Extension Points

  1. Custom Email Events: Extend the EmailSentEvent or create your own:

    class CustomEmailEvent extends EmailSentEvent
    {
        public function getCustomData(): array { /* ... */ }
    }
    
  2. Template Preprocessors: Add logic before rendering templates via a compiler pass or event listener:

    public function onEmailRender(EmailRenderEvent $event): void
    {
        $event->setTemplateData(array_merge($event->getTemplateData(), ['custom_var' => true]));
    }
    
  3. Transport Factories: Create custom transports (e.g., for AWS SES):

    class AWSSesTransportFactory implements TransportFactoryInterface
    {
        public function createTransport(array $options): TransportInterface
        {
            return new AWSSesTransport($options);
        }
    }
    

    Register in config/packages/sylius_mailer.yaml:

    sylius_mailer:
        mailer:
            transport: 'aws_ses'
    
  4. Bulk Email Optimization: Use batch processing for large email lists:

    foreach ($emails as $batch) {
        $sender->sendBatch($batch);
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo