Mail API
TYPO3 provides a RFC-compliant mailing solution based on symfony/mailer for sending emails and symfony/mime for creating email messages.
TYPO3’s backend functionality already ships with a default layout for templated emails, which can be tested out in TYPO3’s install tool test email functionality.
Table of Contents
Configuration
Several settings are available via Admin Tools > Settings > Configure
Installation-Wide Options > Mail which are stored into
$GLOBALS
. See MAIL settings for
an overview of all settings.
Note
If you want to send emails using Microsoft 365 or Office 365, you have to configure a connector first, as described in the article Configure a connector to send mail using Microsoft 365 or Office 365 SMTP relay.
Format
$GLOBALS
can be both
, plain
or
html
. This option can be overridden in the project's
config/
or config/
files.
Fluid paths
All Fluid-based template paths can be configured via
$GLOBALS
['TYPO3_ CONF_ VARS'] ['MAIL'] ['layout Root Paths'] $GLOBALS
['TYPO3_ CONF_ VARS'] ['MAIL'] ['partial Root Paths'] $GLOBALS
['TYPO3_ CONF_ VARS'] ['MAIL'] ['template Root Paths']
where TYPO3 reserves all array keys below 100
for internal purposes.
If you want to provide custom templates or layouts, set this in your
config/
/ config/
file:
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['templateRootPaths'][700]
= 'EXT:my_site_extension/Resources/Private/Templates/Email';
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['layoutRootPaths'][700]
= 'EXT:my_site_extension/Resources/Private/Layouts';
transport
The most important configuration option for sending emails is
$GLOBALS
, which can take the
following values:
smtp
$GLOBALS
['TYPO3_ CONF_ VARS'] ['MAIL'] ['transport'] = 'smtp'; - Sends messages over SMTP. It can deal with encryption and authentication. Works exactly the same on Windows, Unix and MacOS. Requires a mail server and the following additional settings:
$GLOBALS
['TYPO3_ CONF_ VARS'] ['MAIL'] ['transport_ smtp_ server'] = '<server: port>'; - Mail server name and port to connect to. Port defaults to
25
. $GLOBALS
['TYPO3_ CONF_ VARS'] ['MAIL'] ['transport_ smtp_ encrypt'] = <bool>; - Determines whether the transport protocol should be encrypted. Requires
OpenSSL library. Defaults to
false
. Iffalse
, symfony/mailer will use STARTTLS. $GLOBALS
['TYPO3_ CONF_ VARS'] ['MAIL'] ['transport_ smtp_ username] = '<username>'; - The username, if your SMTP server requires authentication.
$GLOBALS
['TYPO3_ CONF_ VARS'] ['MAIL'] ['transport_ smtp_ password] = '<password>'; - The password, if your SMTP server requires authentication.
Example:
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport'] = 'smtp';
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport_smtp_server'] = 'localhost';
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport_smtp_encrypt'] = true;
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport_smtp_username'] = 'johndoe';
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport_smtp_password'] = 'cooLSecret';
// Fetches all 'returning' emails:
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress'] = 'bounces@example.org';
sendmail
$GLOBALS
['TYPO3_ CONF_ VARS'] ['MAIL'] ['transport'] = 'sendmail'; - Sends messages by communicating with a locally installed MTA - such as sendmail. This may require setting the additional option:
$GLOBALS
['TYPO3_ CONF_ VARS'] ['MAIL'] ['transport_ sendmail_ command'] = '<command>'; -
The command to call to send an email locally. The default works on most modern Unix-based mail servers (sendmail, postfix, exim).
Example:
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport'] = 'sendmail'; $GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport_sendmail_command'] = '/usr/sbin/sendmail -bs';
Copied!Attention
Depending on the configuration of the server and the TYPO3 instance, it may not be possible to send emails to BCC recipients. The configuration of the
$GLOBALS
value is crucial.['TYPO3_ CONF_ VARS'] ['MAIL'] ['transport_ sendmail_ command'] TYPO3 recommends the parameter
-bs
(instead of-t -
). The parameteri -bs
tells TYPO3 to use the SMTP standard and that way the BCC recipients are properly set. Symfony refers to the problem of using the-t
parameter as well. Since forge#65791 thetransport_
is automatically set from the PHP runtime configuration and saved. Thus, if you have problems with sending emails to BCC recipients, check the above mentioned configuration.sendmail_ command
mbox
$GLOBALS
['TYPO3_ CONF_ VARS'] ['MAIL'] ['transport'] = 'mbox'; - This doesn't send any email out, but instead will write every outgoing email to a file adhering to the RFC 4155 mbox format, which is a simple text file where the emails are concatenated. Useful for debugging the email sending process and on development machines which cannot send emails to the outside. The file to write to is defined by:
$GLOBALS
['TYPO3_ CONF_ VARS'] ['MAIL'] ['transport_ mbox_ file'] = '</ abs/ path/ to/ mbox/ file>'; - The file where to write the emails into. The path must be absolute.
<classname>
$GLOBALS
['TYPO3_ CONF_ VARS'] ['MAIL'] ['transport'] = '<classname>'; - Custom class which implements
\Symfony\
. The constructor receives all settings from theComponent\ Mailer\ Transport\ Transport Interface MAIL
section to make it possible to add custom settings.
Validators
New in version 11.0
Using additional validators can help to identify if a provided email address
is valid or not. By default, the validator
\Egulias\
is used. The following
validators are available:
\Egulias\
Email Validator\ Validation\ DNSCheck Validation \Egulias\
Email Validator\ Validation\ Spoof Check Validation \Egulias\
Email Validator\ Validation\ No RFCWarnings Validation
Additionally, it is possible to provide an own implementation by implementing
the interface \Egulias\
.
If multiple validators are provided, each validator must return true
.
Example:
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['validators'] = [
\Egulias\EmailValidator\Validation\RFCValidation::class,
\Egulias\EmailValidator\Validation\DNSCheckValidation::class
];
Spooling
The default behavior of the TYPO3 mailer is to send the email messages immediately. However, you may want to avoid the performance hit of the communication to the email server, which could cause the user to wait for the next page to load while the email is being sent. This can be avoided by choosing to "spool" the emails instead of sending them directly.
Spooling in memory
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport_spool_type'] = 'memory';
When you use spooling to store the emails to memory, they will get sent right before the kernel terminates. This means the email only gets sent if the whole request got executed without any unhandled exception or any errors.
Spooling using files
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport_spool_type'] = 'file';
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport_spool_filepath'] = '/folder/of/choice';
When using the filesystem for spooling, you need to define in which folder TYPO3 stores the spooled files. This folder will contain files for each email in the spool. So make sure this directory is writable by TYPO3 and not accessible to the world (outside of the webroot).
Additional notes about the mail spool path:
- If the path is absolute, the path must either start with the root path of the TYPO3 project or the public web folder path
- If the path is relative, the public web path is prepended to the path
- The path must not contain symlinks (important for environments with auto deployment)
- The path must not contain
//
,..
or\
Sending spooled mails
To send the spooled emails you need to run the following CLI command:
vendor/bin/typo3 mailer:spool:send
typo3/sysext/core/bin/typo3 mailer:spool:send
This command can be set up to be run periodically using the TYPO3 Scheduler.
How to create and send emails
There are two ways to send emails in TYPO3 based on the Symfony API:
- With Fluid, using
\TYPO3\
CMS\ Core\ Mail\ Fluid Email - Without Fluid, using
\TYPO3\
CMS\ Core\ Mail\ Mail Message
\TYPO3\
and \TYPO3\
inherit from \Symfony\
and have a similar API.
FluidEmail is specific for sending emails based on Fluid.
Either method can be used to send emails with HTML content, text content or both (HTML and text).
Send email with FluidEmail
This sends an email using a Fluid template Tips
, make
sure the paths are setup as described in Fluid paths:
use Symfony\Component\Mime\Address;
use TYPO3\CMS\Core\Mail\FluidEmail;
use TYPO3\CMS\Core\Mail\MailerInterface;
$email = new FluidEmail();
$email
->to('contact@example.org')
->from(new Address('jeremy@example.org', 'Jeremy'))
->subject('TYPO3 loves you - here is why')
->format(FluidEmail::FORMAT_BOTH) // send HTML and plaintext mail
->setTemplate('TipsAndTricks')
->assign('mySecretIngredient', 'Tomato and TypoScript');
GeneralUtility::makeInstance(MailerInterface::class)->send($email);
Changed in version 12.1
Until TYPO3 v12.0 the \TYPO3\
class
implementation has to be retrieved/injected to send an email. Since TYPO3
v12.1 it is recommended to use \TYPO3\
instead to be able to use custom mailer implementations.
A file Tips
must exist in one of the paths defined in
$GLOBALS
for sending the
HTML content. For sending plaintext content, a file Tips
should exist.
Defining a custom email subject in a custom Fluid template:
<f:section name="Subject">New Login at "{typo3.sitename}"</f:section>
Building templated emails with Fluid also allows to define the language key, and use this within the Fluid template:
$email = new FluidEmail();
$email
->to('contact@example.org')
->assign('language', 'de');
In Fluid, you can now use the defined language key ("language"):
<f:translate languageKey="{language}" id="LLL:EXT:my_ext/Resources/Private/Language/emails.xml:subject" />
Set the current request object for FluidEmail
In order to use ViewHelpers that need a valid current request, such as Uri.page ViewHelper <f:uri.page>, pass the current request to the FluidEmail instance:
use TYPO3\CMS\Core\Mail\FluidEmail;
$email = new FluidEmail();
$email->setRequest($this->request);
Read more aboout Getting the PSR-7 request object in different contexts. In a context where no valid request object can be retrieved, such as in a Console command the affected ViewHelpers cannot be used.
Trying to use these ViewHelpers without a valid request throws an error like the following:
[ERROR] The rendering context of ViewHelper f:link.page is missing a valid request object.
Send email with MailMessage
Mail
can be used to generate and send an email without using
Fluid:
use Symfony\Component\Mime\Address;
use TYPO3\CMS\Core\Mail\MailMessage;
use TYPO3\CMS\Core\Utility\GeneralUtility;
// Create the message
$mail = GeneralUtility::makeInstance(MailMessage::class);
$email = new MailMessage();
// Prepare and send the message
$mail
// Defining the "From" email address and name as an object
// (email clients will display the name)
->from(new Address('john.doe@example.org', 'John Doe'))
// Set the "To" addresses
->to(
new Address('receiver@example.org', 'Max Mustermann'),
new Address('other@example.org')
)
// Give the message a subject
->subject('Your subject')
// Give it the text message
->text('Here is the message itself')
// And optionally an HTML message
->html('<p>Here is the message itself</p>')
// Optionally add any attachments
->attachFromPath('/path/to/my-document.pdf')
// And finally send it
->send()
;
Or, if you prefer, do not concatenate the calls:
use Symfony\Component\Mime\Address;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Mail\MailMessage;
$email = new MailMessage();
$mail->from(new Address('john.doe@example.org', 'John Doe'));
$mail->to(
new Address('receiver@example.org', 'Max Mustermann'),
new Address('other@example.org')
);
$mail->subject('Your subject');
$mail->text('Here is the message itself');
$mail->html('<p>Here is the message itself</p>');
$mail->attachFromPath('/path/to/my-document.pdf');
$mail->send();
Note
Before TYPO3 v10 the Mail
class only had methods like
->set
, set
, ->set
etc.
Now the class inherits from \Symfony\
which
provides the methods from the example. To make migration from older TYPO3
versions easier the previous methods still exist. The use of
Mail
in own extensions is recommended.
How to add attachments
Attach files that exist in your file system:
// Attach file to message
$mail->attachFromPath('/path/to/documents/privacy.pdf');
// Optionally you can tell email clients to display a custom name for the file
$mail->attachFromPath('/path/to/documents/privacy.pdf', 'Privacy Policy');
// Alternatively attach contents from a stream
$mail->attach(fopen('/path/to/documents/contract.doc', 'r'));
How to add inline media
Add some inline media like images in an email:
// Get the image contents from a PHP resource
$mail->embed(fopen('/path/to/images/logo.png', 'r'), 'logo');
// Get the image contents from an existing file
$mail->embedFromPath('/path/to/images/signature.png', 'footer-signature');
// reference images using the syntax 'cid:' + "image embed name"
$mail->html('<img src="cid:logo"> ... <img src="cid:footer-signature"> ...');
How to set and use a default sender
It is possible to define a default email sender ("From:") in Admin Tools > Settings > Configure Installation-Wide Options:
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress'] = 'john.doe@example.org';
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName'] = 'John Doe';
This is how you can use these defaults:
use TYPO3\CMS\Core\Mail\MailMessage;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MailUtility;
$from = MailUtility::getSystemFrom();
$email = new MailMessage();
// As getSystemFrom() returns an array we need to use the setFrom method
$email->setFrom($from);
// ...
$email->send();
In case of the problem "Mails are not sent" in your extension, try to set a
ReturnPath:
. Start as before but add:
use TYPO3\CMS\Core\Utility\MailUtility;
// You will get a valid email address from 'defaultMailFromAddress' or if
// not set from PHP settings or from system.
// If result is not a valid email address, the final result will be
// no-reply@example.org.
$returnPath = MailUtility::getSystemFromAddress();
if ($returnPath != "no-reply@example.org") {
$mail->setReturnPath($returnPath);
}
$mail->send();
Register a custom mailer
New in version 12.1
To be able to use a custom mailer implementation in TYPO3, the interface
\TYPO3\
is available, which extends
\Symfony\
. By default,
\TYPO3\
is registered as implementation.
After implementing your custom mailer, add the following lines into the
Configuration/
file to ensure that your custom
mailer is used.
TYPO3\CMS\Core\Mail\MailerInterface:
alias: MyVendor\SitePackage\Mail\MyCustomMailer
PSR-14 events on sending messages
Some PSR-14 events are available:
- AfterMailerInitializationEvent to add custom mailing settings.
- BeforeMailerSentMessageEvent to manipulate messages before they are sent by the mailer.
- AfterMailerSentMessageEvent to further process a sent message.
Symfony mail documentation
Please refer to the Symfony documentation for more information about available methods.