ylliX - Online Advertising Network Sending Emails in Shopware Using Database Templates - Yet Another Programmer's Blog

Sending Emails in Shopware Using Database Templates

In this tutorial, you’ll learn how to send emails in Shopware 6 using templates stored in the database. We’ll walk through creating a custom service, fetching a mail template by its technical name, and sending it with dynamic customer data.

Introduction

Shopware 6 comes with a powerful mailing system that allows you to create and manage templates directly in the administration panel. But what if you need to trigger an email programmatically — for example, when a custom event happens in your plugin?

In this guide, we’ll build a service class that loads a mail template from the database and uses Shopware’s AbstractMailService to send it to the customer.

Step 1: Inject Dependencies

To interact with Shopware’s mail system, we need two things:

  • AbstractMailService – responsible for sending emails.

  • Mail template repositories – to fetch templates by their type and technical name.

Here’s the constructor of our service:

public function __construct(
    private readonly AbstractMailService $mailService,
    private readonly EntityRepository    $mailTemplateRepository,
    private readonly EntityRepository    $mailTemplateTypeRepository
) {}

Both repositories will be injected automatically by Shopware’s DI container.

Step 2: Fetching the Template

Every mail template in Shopware is connected to a mail template type. To locate the correct template, we first search the type by its technicalName. Then, we fetch the default system template for that type.

private function getMailTemplate(string $id, Context $context): ?MailTemplateEntity
{
    $criteria = new Criteria();
    $criteria->addFilter(new EqualsFilter('technicalName', $id));

    $mailTemplateType = $this->mailTemplateTypeRepository->search($criteria, $context)->first();

    $criteria = new Criteria();
    $criteria->addFilter(
        new MultiFilter(
            MultiFilter::CONNECTION_AND,
            [
                new EqualsFilter('mailTemplateTypeId', $mailTemplateType->getId()),
                new EqualsFilter('systemDefault', true),
            ]
        )
    );

    return $this->mailTemplateRepository->search($criteria, $context)->first();
}

Here we pass in the technical name (test-plugin.template-name) when calling this method.

Step 3: Preparing the Email Data

With the template loaded, we can extract subject, content, and sender details. We also provide the recipient list (in this case, the current customer).

public function sendTemplateMail(Context $context, CustomerEntity $customer): void
{
    $mailTemplate = $this->getMailTemplate('flex-test-plugin.ticket.created', $context);

    $data = [
        'recipients' => [
            $customer->getEmail() => $customer->getFirstName() . ' ' . $customer->getLastName(),
        ],
        'contentHtml'  => $mailTemplate->getContentHtml(),
        'contentPlain' => $mailTemplate->getContentPlain(),
        'subject'      => $mailTemplate->getSubject(),
        'senderName'   => $mailTemplate->getSenderName(),
    ];

    $this->mailService->send($data, $context, ['customer' => $customer]);
}

Notice the third parameter in send():
We pass a data array (['customer' => $customer]) that can be used inside the email template placeholders (Twig variables).

Step 4: Creating a Template in the Admin

To make this work, you must create a mail template type and a mail template in the administration:

  1. Go to Settings → Email Templates.

  2. Create a new template type with technical name test-plugin.template-name.

  3. Add a new template for that type, including subject, HTML, and plain text content.

  4. Use Twig variables like {{ customer.firstName }} inside the template.

Step 5: Triggering the Email

Now you can use your service from anywhere in your plugin:

$this->mailSender->sendTemplateMail($context, $customer);

For example, you might trigger it when a support ticket is created or a custom entity is updated.

Conclusion

You now have a reusable service for sending templated emails in Shopware 6. By separating logic into a service class, you gain full control over when and how your templates are used, while still leveraging the administration for template content management.

Leave a Reply