Joomla Mail Templates and Email Settings: com_mails, Languages, Tags, Mailer Options and SMTP XOAuth2
|
This content was generated with the assistance of AI and should be verified against the official Joomla documentation before being relied on in production. This sub-section’s Joomla bibliography lists the reference material consulted while preparing these pages. |
This page describes how Joomla sends e-mail as it was on 2026-10-30, the date on which its facts were checked against the Joomla! User Guide (https://guide.joomla.org/), the Joomla 6.2 release announcement and the source tree of the CMS. It was written against Joomla 6.2.x (PHP 8.3 or later); the Mail Templates component and the PHP Mail, Sendmail and SMTP mailers behave the same in the 5.4 security-only line, while SMTP OAuth 2.0 authentication exists only from Joomla 6.2. The running example is the Tallpine Hiking Club site: the club sends registration and password-reset messages to members, a monthly mass mail from the board, contact-form notifications to the secretary and Joomla update notifications to the webmaster, and wants all of them in the club’s voice, in English and German, delivered through the club’s Microsoft 365 mailbox.
E-mail touches four kinds of people. Editors and site builders rewrite the wording of the system messages. Administrators
choose the mailer and make delivery reliable. Themers restyle the HTML frame shared by all messages. Developers send their
own messages from com_tallpine and register them as editable templates.
How Joomla sends e-mail
Every message Joomla sends, whether it is a registration activation, a contact-form copy, a Smart Search or privacy notice or a scheduled-task notification, goes through the same two layers.
-
Content. Since Joomla 4.0 the component
com_mails(System, Mail Templates) stores the wording of system messages in the database table#__mail_templates, one row per template and language. Before 4.0 the wording lived in language-file strings that an editor could change only through the Language Overrides tool. -
Transport. The mailer selected in System, Global Configuration, Server, Mail delivers the finished message: PHP Mail, Sendmail or SMTP. Joomla 6.2 adds OAuth 2.0 as an authentication method for SMTP.
The User Guide introduction to Mail Templates describes the feature as one that lets administrators change the e-mails
Joomla sends when users and administrators act, without editing code, for both built-in templates and templates added by
third-party extensions. That page labels the feature "Introduced in Joomla 5.2", whereas the com_mails component and its
#__mail_templates table exist from Joomla 4.0, and the Joomla! 4 Masterclass (2023) already documents Mail Templates
for 4.x. The two statements are reconcilable only if the User Guide label refers to part of the current feature set, such
as the options screen with layouts and logo, so treat 4.0 as the arrival of the component and check the Options screen
of your own version for the individual settings listed below.
The Mail Templates screens
Open System, then Mail Templates (the User Guide documents it as a section of its own). The list
shows one row per template, with its title, the extension that owns it, the template ID and the languages in which it has
been customised. Joomla’s own templates have IDs such as com_users.registration.user.admin_activation; a third-party
extension, such as com_tallpine, adds its own IDs in the same extension.context style, and the template list groups
them by extension.
Select a template and Joomla asks for a language if more than one content language is installed. This is the key idea of
the component: a template is edited per language. The row with the empty language is the default shipped with the
extension; once you save a German version for de-DE, that row is used for German recipients and the default stays for
everybody else.
The edit screen
On the edit screen the title, the ID and the description of the template are shown but cannot be changed. The fields you can edit are:
-
Subject, the subject line of the message.
-
Body, the text of the message. The editor is HTML or plain text depending on the global Mail Format (below).
-
HTML Body when the Mail Format is Both, in which case the plain-text and the HTML versions are edited separately.
-
A list of tags to the right of the editor. Only the tags listed there work in that template, and clicking one inserts it at the cursor.
-
An Options tab, which overrides the global settings for this one template (see below).
Placeholder tags
Tags are upper-case words in braces, such as {NAME}, {SITENAME} or {ACTIVATE}. Joomla replaces them
case-insensitively at send time. Most tags are single values. The exception is {MESSAGES}: the text between
{MESSAGES} and {/MESSAGES} is repeated once for every message the extension supplies, which is how the default
User Actions Log notification builds one table row per logged action.
The set of tags depends on the template. The User Guide has a cross-reference table, from which these examples come:
| Tag | Used by |
|---|---|
|
Every extension except the User Actions Log |
|
Users, Contacts and the user plugin (not every tag in every template) |
|
Users (account activation link, clear-text password sent by some templates) |
|
Users, Mass Mail Users template only |
|
Multi-factor Authentication |
|
The scheduled Joomla update notification task |
|
User Actions Log |
|
Messaging and Privacy |
Two tags deserve a security comment. {PASSWORDCLEAR} puts a clear-text password into an e-mail, which is exactly what
a modern site should avoid, so prefer the activation and reset flows that send a link, and remove the tag from templates
that you copy forward. Tags that carry user-supplied text, such as {BODY} in a contact message, end up in the HTML version; developers mark such tags with addUnsafeTags() so they are escaped, and nobody should paste user data into the HTML layout without escaping it.
Customising the Tallpine welcome message
The club wants the account-activation mail to say that the trail reports are for members only. In Mail Templates open the activation template, choose German or English and rewrite the body around the tags. The English plain-text version could read:
Hello {NAME},
welcome to the Tallpine Hiking Club website. Before you can read the member-only
trail conditions, please confirm your address:
{ACTIVATE}
If you did not register, ignore this message and the account will be removed.
-- {SITENAME}
Test every language you ship. A template that has no row for the recipient’s language falls back to the default row, so a German member simply receives English text until you add the German version, with no error.
Options: HTML, plain text and per-template settings
The Options button on the Mail Templates list (the same settings are reachable from Global Configuration under Mail Templates) holds the global behaviour. The User Guide lists these:
| Setting | Effect |
|---|---|
Mail Format |
HTML, Plaintext or Both. With Both each template has two editors and Joomla sends a multipart message, so mail clients that do not render HTML still show the plain text. |
Per Template Mail Settings |
When Yes, a template may use its own mail account and layout, set on its Options tab, instead of the global defaults. |
Send Copy |
Sends a copy (the source code adds it as a blind copy) of each message to the site’s default address. It does not apply to templates that define their own settings. |
Attachments Folder |
A folder, relative to the site root, holding the files that templates may attach. Only templates that support attachments use it, and each attachment is resolved inside this folder. |
Mail Template Layout and Layout |
Enable a layout and choose which one; Use Default selects the distribution layout. |
Logo File |
An image placed centred at the top of every message, followed by a line. A single template can omit it, but an individual message cannot. |
Two extra options live elsewhere. On Users, Options, the Mass Mail Users tab has a subject prefix and a body suffix that
feed the {SUBJECTPREFIX} and {BODYSUFFIX} tags of the Users: Mass Mail Users template; if the template lacks the tags,
the text is not sent although it appears on the screen. On the User Actions Log options, Events To Log controls which
actions appear in the {MESSAGE} tag of its notification template (see
Privacy and Action Logs).
Which format to choose
The source of the MailTemplate class shows the exact rules, and they explain several surprises.
-
Plaintext sets only the plain body, HTML only the HTML body, Both sets both and the plain text becomes the alternative body of a multipart message.
-
If the plain body is empty, Joomla generates it from the HTML by turning line breaks into newlines and stripping tags; if the HTML body is empty, it is generated from the plain body with
nl2br. A one-format template therefore still sends a readable message. -
Relative URLs in the HTML body are converted to absolute ones before sending, and the logo, when enabled, is attached inline.
For a club newsletter the practical choice is Both: accessible and spam-filter friendly, with the branded HTML as the first choice for clients that can show it. Choose Plaintext only for sites whose recipients or policies require it.
Per-template mail settings
With Per Template Mail Settings on, the Options tab of a template can replace the sender and the transport for that
template alone. The class reads the keys alternative_mailconfig, mailer (smtp or sendmail), smtpauth,
smtpuser, smtppass, smtphost, smtpsecure, smtpport, mailfrom, fromname, replyto and replytoname, and
uses the values of Global Configuration as fallbacks. For the Tallpine site this lets the contact-form template send
from secretary@tallpine.example while everything else uses the no-reply address. The SMTP password of such a template
is stored in the database in the template’s parameters, so use this feature sparingly and protect database backups.
Layouts: restyling every message
The wording lives in the template, but the frame (logo, width, footer with the site name and the year) lives in a PHP layout.
The distribution layout is layouts/joomla/mail/mailtemplate.php, a three-row table: logo or site name, the message, and
a copyright footer with a link to the site.
To change it without losing the change at the next update, create a template override: in System, Site Templates open
cassiopeia_tallpine, choose the Create Overrides tab and select joomla, then mail. Joomla copies the file into
templates/cassiopeia_tallpine/html/layouts/joomla/mail/. Every .php file in that folder appears in the Layout list
of the Mail Templates options, so you can keep several layouts and select one per template.
The layout receives its data in the $displayData array: mail is the HTML body (the layout returns nothing if it is
empty), and the optional extra array carries lang, logo (the file name used as a cid: inline image) and
siteName. The body is printed unescaped, so everything that reaches it must already be safe HTML. A reduced Tallpine
layout:
<?php
/**
* Tallpine mail layout: templates/cassiopeia_tallpine/html/layouts/joomla/mail/tallpine.php
*/
defined('_JEXEC') or die;
use Joomla\CMS\Uri\Uri;
$mailBody = $displayData['mail'] ?? '';
$extra = $displayData['extra'] ?? [];
$siteName = htmlspecialchars($extra['siteName'] ?? 'Tallpine Hiking Club', ENT_QUOTES, 'UTF-8');
$lang = htmlspecialchars($extra['lang'] ?? 'en', ENT_QUOTES, 'UTF-8');
if ($mailBody === '') {
return;
}
?>
<!DOCTYPE html>
<html lang="<?php echo $lang; ?>">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body style="margin:0;background:#f3f5f2;font-family:Arial,Helvetica,sans-serif;color:#1d2b24">
<table role="presentation" width="94%" style="max-width:630px;margin:0 auto;background:#ffffff">
<tr><td style="padding:16px;background:#2f5d46;color:#ffffff">
<strong><?php echo $siteName; ?></strong>
</td></tr>
<tr><td style="padding:16px"><?php echo $mailBody; ?></td></tr>
<tr><td style="padding:12px;font-size:12px;color:#555">
© <?php echo date('Y'); ?> <?php echo $siteName; ?> -
<a href="<?php echo Uri::root(false); ?>"><?php echo Uri::root(false); ?></a>
</td></tr>
</table>
</body>
</html>
Use tables and inline styles, as above: mail clients ignore most external CSS and the Web Asset Manager is not involved, because the message is not a web page. Do not rely on JavaScript, web fonts or CSS variables. Send a test through the Mass Mail Users template to a test group containing an address you control. For overrides in general see Template Overrides and Alternative Layouts.
Mass mail
Users, Mass Mail Users sends a one-off message to the members of selected groups. It uses its own mail template, so the same layout, logo and format apply, and the subject prefix and body suffix of the Users options are added around the text. For the Tallpine board’s monthly newsletter, send to the Registered group, and prefer a dedicated newsletter extension for large lists: a single SMTP session sending thousands of messages is slow, is limited by the provider’s rate caps and can get the club’s domain blocklisted. See Users, Groups, Access Levels and ACL for groups.
Mail settings in Global Configuration
The transport is chosen in System, Global Configuration, Server tab, Mail panel (see
Global Configuration for the other panels). The settings stored in
configuration.php correspond one to one.
| Setting | Notes |
|---|---|
Mailer |
PHP Mail, Sendmail or SMTP. The User Guide suggests trying them in that order. |
From Email, From Name |
The sender of messages. Providers often require that it matches the authenticated mailbox (see the OAuth section). |
Send Mail |
Switching it off disables sending: the mailer throws a "mail disabled" exception for every attempt, so users who register on a site where it is off see an error. |
Sendmail Path |
The binary used by the Sendmail mailer. If empty, Joomla falls back to the PHP |
SMTP Host, SMTP Port |
Host name of the outgoing server (the default |
SMTP Security |
None, SSL/TLS or STARTTLS. The default is None. |
SMTP Authentication |
No by default; with Yes the username and password fields appear. Joomla 6.2 adds OAuth 2.0 as a method. |
SMTP Username, SMTP Password |
Credentials of the mailbox. |
Send Test Mail |
Sends a message to confirm the settings, using the values currently typed into the form. |
PHP Mail, Sendmail or SMTP
PHP Mail calls the PHP mail() function and relies on the server’s own mail setup. It needs no credentials and is the
default, but it gives you no log of rejections, usually sends from the hosting server’s IP address and is the most
likely to land in spam. Sendmail hands the message to a local binary (Postfix and Exim provide a compatible one) and
suits a server you administer. SMTP speaks to a mail server and is the right choice for any site that matters: you get an
error when delivery fails, the provider signs and authenticates the mail, and the sending reputation is the provider’s.
The source shows that if SMTP is selected but the host is empty, or authentication is on without credentials, Joomla
silently falls back to PHP Mail, so a mis-saved form does not stop mail but changes how it is sent.
The User Guide also documents Gmail with a password: host smtp.gmail.com, port 465 with SSL/TLS or 587 with STARTTLS,
authentication on, and an app-specific password instead of the account password when 2-Step Verification is on. The PHP
OpenSSL extension must be enabled. The Guide’s SMTP page remains the reference for that classic setup; the next section
replaces the stored password with a token.
Keeping credentials out of the database and the repository
Global Configuration stores the SMTP password in configuration.php. Do not commit that file. In a container deployment,
generate it from environment variables at start-up, and make it unreadable by other system users (see
configuration.php and .htaccess). The relevant properties look like
this, with placeholders:
public $mailonline = true;
public $mailer = 'smtp';
public $mailfrom = 'noreply@tallpine.example';
public $fromname = 'Tallpine Hiking Club';
public $smtphost = 'smtp.office365.com';
public $smtpport = 587;
public $smtpsecure = 'tls';
public $smtpauth = true;
public $smtpuser = 'noreply@tallpine.example';
public $smtppass = 'CHANGE_ME';
With the OAuth 2.0 method described next there is no SMTP password to store at all.
SMTP OAuth 2.0 (XOAuth2) in Joomla 6.2
Providers increasingly restrict password-based SMTP sign-in, and Google requires app passwords when 2-Step Verification is on. Joomla 6.2 answers with generic XOAuth2 support. The release announcement states it this way:
instead of storing the password of the SMTP account, Joomla authorises access through the mail provider; the provider
returns a long-lived refresh token, which Joomla later uses to request short-lived access tokens for SMTP
authentication; this is particularly relevant for services such as Microsoft 365 and Google Workspace. In the source,
the SMTP method takes an OAuth token provider object and then sets the PHPMailer authentication type to XOAUTH2.
Source: Joomla 6.2 release announcement
Older books and tutorials, such as the Joomla! 4 Masterclass (2023), describe only the password methods; for Joomla 6.2 prefer OAuth where the provider supports it.
The Joomla side
In System, Global Configuration, Server, Mail set Mailer to SMTP and SMTP Authentication to OAuth 2.0. These fields appear:
| Field | Value |
|---|---|
From Email Address |
Should match the SMTP username. |
SMTP Username |
The mailbox used for SMTP login. |
OAuth2 Client ID |
The public identifier issued by the provider. |
OAuth2 Client Secret |
The private secret; keep it confidential. |
OAuth2 Scope |
The permissions requested, separated by spaces. |
OAuth2 Authorize URL |
Where the mailbox owner signs in and consents. |
OAuth2 Token URL |
Where Joomla exchanges the code and later refreshes tokens. |
The general workflow is the same for every provider: register an OAuth application with the mail provider, register Joomla’s callback URL as an allowed redirect URI, grant the SMTP permissions, create a client ID and secret, publish the application if the provider needs it, wait for the change to propagate (up to roughly an hour), enter the values in Joomla and save, start the authorisation from Joomla, sign in as the SMTP account and consent, confirm that Joomla stored a refresh token and send a test message.
The redirect URI must be registered exactly, with protocol, host, path and query string; registering only the domain is not enough:
https://www.tallpine.example/administrator/index.php?option=com_config&task=mail.oauth2callback&format=raw
Microsoft 365
-
In Microsoft Entra, Identity, Applications, App registrations, create a registration for accounts in this organisational directory only. Note the application (client) ID and the directory (tenant) ID.
-
Under Authentication add a Web platform with the redirect URI above.
-
Add the delegated permissions
SMTP.Sendforhttps://outlook.office.comandoffline_access; an administrator may need to grant consent. -
Under Certificates & secrets create a client secret and copy its Value (not the secret ID) immediately.
-
In the Microsoft 365 admin center, enable Authenticated SMTP for the mailbox. OAuth can succeed while SMTP still fails if this is off.
Joomla values:
SMTP Host: smtp.office365.com
SMTP Port: 587
SMTP Security: STARTTLS
OAuth2 Scope: https://outlook.office.com/SMTP.Send offline_access
OAuth2 Authorize URL: https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/authorize
OAuth2 Token URL: https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/token
Replace TENANT_ID with the directory (tenant) ID. Using a From address different from the SMTP user requires the
mailbox to have "Send As" permission.
Google Workspace and Gmail
-
In Google Cloud Console create or select a project and configure the Google Auth Platform: branding, audience (internal for Workspace-only use; otherwise a publishing status and test users) and data access.
-
Add the scope
https://mail.google.com/. -
Under Clients create an OAuth client of type Web application and add the redirect URI.
-
Publish the app or add the SMTP user as a test user. Copy the client ID and the secret.
SMTP Host: smtp.gmail.com
SMTP Port: 587
SMTP Security: STARTTLS
OAuth2 Scope: https://mail.google.com/
OAuth2 Authorize URL: https://accounts.google.com/o/oauth2/v2/auth
OAuth2 Token URL: https://oauth2.googleapis.com/token
The Gmail scope is classified as sensitive or restricted, so a public application may need Google verification; a private Workspace application with an internal audience avoids that. If the app is unpublished, authorisation is blocked for users not added as test users. From addresses that differ from the account need an alias or delegation.
Pitfalls and security
-
Redirect mismatch. Any difference in the redirect URI, including a change from
wwwto the bare host or from HTTP to HTTPS behind a reverse proxy, breaks authorisation. Make sure the site knows it is served over HTTPS (see Web Server, Reverse Proxy and HTTPS). -
Propagation delay. Changes at the provider can take about an hour.
-
Wrong secret field. Microsoft shows both an ID and a value; only the value works.
-
Refresh tokens expire or are revoked when the mailbox password changes, the user is disabled or a policy forces re-consent; the symptom is that mail stops until you authorise again from Joomla. Monitor delivery.
-
Use a dedicated mailbox with the least privileges, such as a no-reply user, and a single-tenant app registration.
-
The client secret is still a secret: do not paste it into tickets, do not commit exports of
configuration.php, and do not share one registration between unrelated sites. Microsoft client secrets also expire, so note the expiry date and rotate. -
Do not lower SMTP Security to None to "make it work".
Testing with Mailpit
Test mail on a developer machine must never reach real members. Mailpit is a local SMTP server with a web inbox that accepts and stores every message. The Compose file of Local Development with Docker already runs it; the essential parts are:
services:
joomla:
image: joomla:6.2-php8.4-apache
environment:
JOOMLA_SMTP_HOST: mailpit
JOOMLA_SMTP_HOST_PORT: "1025"
mailpit:
image: axllent/mailpit:v1.27
ports:
- "8025:8025"
environment:
MP_SMTP_AUTH_ACCEPT_ANY: "1"
MP_SMTP_AUTH_ALLOW_INSECURE: "1"
Source: Mailpit: Docker install
If your site was installed by hand, set the same values in Global Configuration: Mailer SMTP, host mailpit, port 1025,
security None, authentication No. Then:
-
Click Send Test Mail and open
http://localhost:8025: the message must be in the inbox. -
Edit the activation template, register a test member and read the message in Mailpit, which also shows the HTML and the plain-text parts and a link check.
-
Switch the Mail Format to Both and compare. Add a German version and register with the German interface to confirm the language fallback.
-
Break the setup on purpose (stop the container) and see the error the site reports.
Staging sites should use Mailpit or an equivalent sink too, so a copy of the production database does not mail real users. Never copy the production SMTP settings or the OAuth client secret to staging.
If delivery fails with a real provider, the User Guide’s recipe is: enable the System - Debug plugin restricted to Super
Users, set Debug System to Yes, Error Reporting to Maximum, Log Almost Everything to Yes, set the Log Categories of the
custom logging to mail, press Send Test Mail and read administrator/logs/everything.php.
Sending your own mail from com_tallpine
Developers should not call the mailer directly for messages an administrator may want to reword. The class
Joomla\CMS\Mail\MailTemplate sends a registered template. Its constructor takes the template ID and the language, and
optional mailer, language-factory and database arguments (omitting them is deprecated and triggers a notice, so inject
them from the container). The methods used most are addRecipient($mail, $name, $type) with type to, cc or bcc,
addTemplateData($data, $plain) for the tag values, addUnsafeTags($tags) for tags to be HTML-escaped,
addAttachment($name, $file), setReplyTo() and send(). The template row is loaded by template ID and language, with
the language-specific row taking precedence over the empty-language default; send() returns false when no row exists.
<?php
namespace Tallpine\Component\Tallpine\Site\Service;
\defined('_JEXEC') or die;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Mail\MailTemplate;
final class TrailClosureNotifier
{
public function notify(string $recipient, string $recipientName, string $trailTitle, string $language): bool
{
$mail = new MailTemplate('com_tallpine.trail.closed', $language);
$mail->addRecipient($recipient, $recipientName);
$mail->addTemplateData([
'NAME' => $recipientName,
'TRAIL' => $trailTitle,
]);
$mail->addUnsafeTags(['name', 'trail']);
return $mail->send();
}
}
Before the first send, the template must exist in #__mail_templates with the ID com_tallpine.trail.closed, an empty
language and the tags it supports. The installer script of pkg_tallpine (see
Installer Scripts and SQL Updates) inserts it with the
MailTemplate::createTemplate() helper or an SQL insert, and the extension language file supplies the readable title.
The static helpers getTemplate(), createTemplate(), updateTemplate() and deleteTemplate() are deprecated in favour
of the com_mails template model, so check the current signatures in the source tree of your minor version; the Developer
Manual has no page on mail templates, which is why this section cites the source.
A message that needs no editable wording, for example from a console command, can use the application mailer obtained from the container; check the source tree of your minor version for the factory to use.
Common errors
-
No mail leaves the site. Check Send Mail, then the Send Test Mail result, then the log; remember the silent fallback to PHP Mail when SMTP is half-configured.
-
Mail arrives in spam. PHP Mail from a shared host is the usual cause. Use SMTP with a provider that signs mail, and set SPF, DKIM and DMARC records for the sender domain; the From address must belong to a domain you control.
-
Edited text does not appear. The recipient’s language has its own row, or Per Template Mail Settings and the layout option are overriding the global setting, or the Mail Format sends only the other version.
-
Tags are shown literally. The tag is not offered in that template, or is misspelled. Tags are not available across templates.
-
The layout is ignored or lost at an update. It must be an override in the active template’s
html/layouts/joomla/mailfolder, and the layout must be selected in the options. -
OAuth authorisation fails. Compare the redirect URI character by character, wait for propagation and, on Microsoft, check that Authenticated SMTP is enabled for the mailbox.
-
Mass mail never finishes. The request times out; send smaller batches through a dedicated service.