diff --git a/libraries/src/Event/CoreEventAware.php b/libraries/src/Event/CoreEventAware.php
index 22a2a74c2b0f2..f9c6cb012dfd4 100644
--- a/libraries/src/Event/CoreEventAware.php
+++ b/libraries/src/Event/CoreEventAware.php
@@ -201,6 +201,8 @@ trait CoreEventAware
         'onPageCacheSetCaching' => PageCache\SetCachingEvent::class,
         'onPageCacheGetKey'     => PageCache\GetKeyEvent::class,
         'onPageCacheIsExcluded' => PageCache\IsExcludedEvent::class,
+        // Mail
+        'onMailBeforeRendering' => Mail\BeforeRenderingMailTemplateEvent::class,
     ];
 
     /**
diff --git a/libraries/src/Event/Mail/BeforeRenderingMailTemplateEvent.php b/libraries/src/Event/Mail/BeforeRenderingMailTemplateEvent.php
new file mode 100644
index 0000000000000..438e0e9d30dff
--- /dev/null
+++ b/libraries/src/Event/Mail/BeforeRenderingMailTemplateEvent.php
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * Joomla! Content Management System
+ *
+ * @copyright  (C) 2024 Open Source Matters, Inc. <https://www.joomla.org>
+ * @license    GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+namespace Joomla\CMS\Event\Mail;
+
+/**
+ * Class for MailTemplate events
+ * Example:
+ *   new BeforeRenderingMailTemplateEvent('onEventName', ['templateId' => 'com_example.template', 'subject' => $mailTemplateInstance]);
+ *
+ * @since  __DEPLOY_VERSION__
+ */
+class BeforeRenderingMailTemplateEvent extends MailTemplateEvent
+{
+    /**
+     * The argument names, in order expected by legacy plugins.
+     *
+     * @var array
+     *
+     * @since  __DEPLOY_VERSION__
+     * @deprecated __DEPLOY_VERSION__ will be removed in 6.0
+     */
+    protected $legacyArgumentsOrder = ['templateId', 'subject'];
+}
diff --git a/libraries/src/Event/Mail/MailTemplateEvent.php b/libraries/src/Event/Mail/MailTemplateEvent.php
new file mode 100644
index 0000000000000..57719d3c40adc
--- /dev/null
+++ b/libraries/src/Event/Mail/MailTemplateEvent.php
@@ -0,0 +1,146 @@
+<?php
+
+/**
+ * Joomla! Content Management System
+ *
+ * @copyright  (C) 2024 Open Source Matters, Inc. <https://www.joomla.org>
+ * @license    GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+namespace Joomla\CMS\Event\Mail;
+
+use Joomla\CMS\Event\AbstractImmutableEvent;
+use Joomla\CMS\Event\ReshapeArgumentsAware;
+use Joomla\CMS\Mail\MailTemplate;
+
+// phpcs:disable PSR1.Files.SideEffects
+\defined('_JEXEC') or die;
+// phpcs:enable PSR1.Files.SideEffects
+
+/**
+ * Base class for MailTemplate events
+ *
+ * @since  __DEPLOY_VERSION__
+ */
+abstract class MailTemplateEvent extends AbstractImmutableEvent
+{
+    use ReshapeArgumentsAware;
+
+    /**
+     * The argument names, in order expected by legacy plugins.
+     *
+     * @var array
+     *
+     * @since  __DEPLOY_VERSION__
+     * @deprecated __DEPLOY_VERSION__ will be removed in 6.0
+     */
+    protected $legacyArgumentsOrder = [];
+
+    /**
+     * Constructor.
+     *
+     * @param   string  $name       The event name.
+     * @param   array   $arguments  The event arguments.
+     *
+     * @throws  \BadMethodCallException
+     *
+     * @since   __DEPLOY_VERSION__
+     */
+    public function __construct($name, array $arguments = [])
+    {
+        // Reshape the arguments array to preserve b/c with legacy listeners
+        if ($this->legacyArgumentsOrder) {
+            $arguments = $this->reshapeArguments($arguments, $this->legacyArgumentsOrder);
+        }
+
+        parent::__construct($name, $arguments);
+
+        if (!\array_key_exists('subject', $this->arguments)) {
+            throw new \BadMethodCallException("Argument 'subject' of event {$name} is required but has not been provided");
+        }
+
+        if (!\array_key_exists('templateId', $this->arguments)) {
+            throw new \BadMethodCallException("Argument 'templateId' of event {$name} is required but has not been provided");
+        }
+    }
+
+    /**
+     * Pre-Setter for the subject argument.
+     *
+     * @param   MailTemplate  $value  The value to set
+     *
+     * @return  MailTemplate
+     *
+     * @since  __DEPLOY_VERSION__
+     */
+    protected function onSetSubject(MailTemplate $value): MailTemplate
+    {
+        return $value;
+    }
+
+    /**
+     * Pre-getter for the subject argument.
+     *
+     * @param   MailTemplate  $value  The value to set
+     *
+     * @return  MailTemplate
+     *
+     * @since  __DEPLOY_VERSION__
+     */
+    protected function onGetSubject(MailTemplate $value): MailTemplate
+    {
+        return $value;
+    }
+
+    /**
+     * Pre-setter for the templateId argument.
+     *
+     * @param   string  $value  The value to set
+     *
+     * @return  string
+     *
+     * @since  __DEPLOY_VERSION__
+     */
+    protected function onSetTemplateId(string $value): string
+    {
+        return $value;
+    }
+
+    /**
+     * Pre-getter for the templateId argument.
+     *
+     * @param   string  $value  The value to set
+     *
+     * @return  string
+     *
+     * @since  __DEPLOY_VERSION__
+     */
+    protected function onGetTemplateId(string $value): string
+    {
+        return $value;
+    }
+
+    /**
+     * Getter for the subject argument.
+     *
+     * @return  MailTemplate
+     *
+     * @since  __DEPLOY_VERSION__
+     */
+    public function getTemplate(): MailTemplate
+    {
+        return $this->getArgument('subject');
+    }
+
+    /**
+     * Getter for the templateId argument.
+     *
+     * @return  string
+     *
+     * @since  __DEPLOY_VERSION__
+     */
+    public function getTemplateId(): string
+    {
+        return $this->getArgument('templateId');
+    }
+}
diff --git a/libraries/src/Mail/MailTemplate.php b/libraries/src/Mail/MailTemplate.php
index f5bbc7f78941d..b48191c3dca7f 100644
--- a/libraries/src/Mail/MailTemplate.php
+++ b/libraries/src/Mail/MailTemplate.php
@@ -10,6 +10,7 @@
 namespace Joomla\CMS\Mail;
 
 use Joomla\CMS\Component\ComponentHelper;
+use Joomla\CMS\Event\Mail\BeforeRenderingMailTemplateEvent;
 use Joomla\CMS\Factory;
 use Joomla\CMS\HTML\HTMLHelper;
 use Joomla\CMS\Language\Text;
@@ -290,7 +291,10 @@ public function send()
             $useLayout   = $params->get('disable_htmllayout', $useLayout);
         }
 
-        $app->triggerEvent('onMailBeforeRendering', [$this->template_id, &$this]);
+        $app->getDispatcher()->dispatch('onMailBeforeRendering', new BeforeRenderingMailTemplateEvent(
+            'onMailBeforeRendering',
+            ['templateId' => $this->template_id, 'subject' => $this]
+        ));
 
         $subject = $this->replaceTags(Text::_($mail->subject), $this->data);
         $this->mailer->setSubject($subject);