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.

  1. 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.

  2. 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.

flowchart LR E[Extension event<br/>registration, reset, contact form] --> M[MailTemplate class] M -->|template_id and language| T[(mail_templates table)] T --> R[Replace tags, apply layout] R --> F{Mail format} F -->|HTML or Both| H[HTML body in joomla.mail layout] F -->|Plaintext or Both| P[Plain-text body] H --> X[Mailer from Global Configuration] P --> X X -->|PHP Mail| A[PHP mail function] X -->|Sendmail| B[sendmail binary] X -->|SMTP| C[SMTP server, password or OAuth 2.0]

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

{SITENAME}

Every extension except the User Actions Log

{NAME}, {USERNAME}, {EMAIL}

Users, Contacts and the user plugin (not every tag in every template)

{ACTIVATE}, {PASSWORDCLEAR}

Users (account activation link, clear-text password sent by some templates)

{SUBJECTPREFIX}, {BODYSUFFIX}

Users, Mass Mail Users template only

{CODE}, {FULLNAME}, {TOKENURL}

Multi-factor Authentication

{CURVERSION}, {NEWVERSION}, {RELEASENEWS}, {LINK}

The scheduled Joomla update notification task

{DATE}, {EXTENSION}, {MESSAGE}, {MESSAGES}

User Actions Log

{TOKEN}, {FORMURL}, {TONAME}

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">
        &copy; <?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 sendmail_path setting, then to /usr/sbin/sendmail.

SMTP Host, SMTP Port

Host name of the outgoing server (the default localhost rarely works) and the port, commonly 25 without encryption, 465 with SSL/TLS or 587 with STARTTLS.

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.

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

  1. 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.

  2. Under Authentication add a Web platform with the redirect URI above.

  3. Add the delegated permissions SMTP.Send for https://outlook.office.com and offline_access; an administrator may need to grant consent.

  4. Under Certificates & secrets create a client secret and copy its Value (not the secret ID) immediately.

  5. 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

  1. 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.

  2. Add the scope https://mail.google.com/.

  3. Under Clients create an OAuth client of type Web application and add the redirect URI.

  4. 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 www to 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"

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:

  1. Click Send Test Mail and open http://localhost:8025: the message must be in the inbox.

  2. 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.

  3. Switch the Mail Format to Both and compare. Add a German version and register with the German interface to confirm the language fallback.

  4. 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/mail folder, 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.