An embedded email image is an image file included directly within the email’s content, allowing it to be displayed inline (i.e., in the body of an HTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. email) without requiring the recipient to download it separately. This is achieved by referencing the image via a Content-ID (CID) in the email’s HTML markup. Embedded images are useful for enhancing visual emails, such as newsletters or branded notifications, but they only work in HTML-formatted emails. By default, WordPress sends emails in plain text format. To take advantage of embedded images, you must set the Content-Type header The header of your site is typically the first thing people will experience. The masthead or header art located across the top of your page is part of the look and feel of your website. It can influence a visitor’s opinion about your content and you/ your organization’s brand. It may also look different on different screen sizes. to text/html when calling wp_mail().
Historically, the only way to add inline embedded images was to directly call $phpmailer->AddEmbeddedImage method during phpmailer_init, like this:
function embed_images( $phpmailer ) {
$phpmailer->AddEmbeddedImage( '/path/to/logo.png', 'logo.png' );
}
add_action( 'phpmailer_init', 'embed_images' );
This worked, but this specific implementation depended on the PHPMailer library.
The changes added in #28059/[60698] aim to provide a native option that facilitates some degree of abstraction from the current mailing library and also sets the stage to deprecate this native injection with phpmailer_init in the future, simplifying the process and ensuring long-term maintainability.
This change updates the wp_mail function signature to add a new argument for $embeds:
wp_mail( $to, $subject, $message, $headers = '', $attachments = array(), $embeds = array())
This new parameter can accept a newline-separated(\n) string of images paths, an array of image path strings, or an associative array of image paths where each key is the Content-ID.
Content-ID formation
When using the $embeds parameter to embed images for use in HTML emails, no changes are necessary for plain text emails. Reference the embedded file in your HTML code with a cid: URL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org whose value matches the file’s Content-ID.
Example email markup:
<img src="cid:0" alt="Logo">
<img src="cid:my-image" alt="Image">
As mentioned above, Content-ID (cid)s for each image path to be embedded can be passed using an associative array of cid/image path pairs. If $embeds is a newline-separated string or a non-associative array, the cid is a zero-based index of either the exploded string or the element’s position in the array.
New wp_mail_embed_args filter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output.
A new wp_mail_embed_args filter has been introduced to allow each individual embed to be filtered during processing. With this new hook, it’s possible to customize most of the properties of each embed before passing to $phpmailer->AddEmbeddedImage().
$embed_args = apply_filters(
'wp_mail_embed_args',
array(
'path' => $embed_path,
'cid' => $key,
'name' => basename( $embed_path ),
'encoding' => 'base64',
'type' => '',
'disposition' => 'inline',
)
);
Each of these values represents the following:
path – The path to the image file
cid – The Content-ID
name – The filename of the image
encoding – The encoding of the image
type – The MIME Content-Type
disposition – The disposition of the image
This provides a 1-to-1 representation of the PHPMailer’s addEmbeddedImage method via this hook.
Example: Set the correct Content-Type when embedding SVG images:
add_filter( 'wp_mail_embed_args', function ( $args ) {
if ( isset( $args['path'] ) && '.svg' === substr( $args['path'], -4 ) ) {
$args['type'] = 'image/svg+xml';
}
return $args;
} );
Backward Compatibility Recommendations
If you are maintaining code that completely replaces the wp_mail() function (e.g. via a custom implementation in a plugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party or theme), take the following steps to improve the implementation with this update:
- Update your implementation to expect and handle the new
$embeds parameter in the function signature. This is optional, as $embeds receives an empty array by default.
- Consider adding support for the
wp_mail_embed_args filter to ensure that any plugins or themes making use of it will have their changes reflected in your implementation of wp_mail().
- If you are currently supporting images in your emails, they won’t be affected by this update. Although, adding this implementation will ensure greater integration with WordPress to safeguard against future deprecations.
As a reminder, fully replacing wp_mail() is generally discouraged. The pre_wp_mail filter introduced in WordPress 5.7 can accomplish the same result. For more details, see the developer note on overriding wp_mail() behavior.
Props to @TimothyBlynJacobs, @mukesh27, @davidbaumwald, @desrosj, and @johnbillion helping review this dev-note.
#6-9, #dev-notes, #dev-notes-6-9, #mail