Customizing Default WordPress Emails Without A Plugin

Learn how to easily customize default WordPress emails like new user registration and password reset messages without needing a plugin.
calendar_today
Published: April 19, 2023
Founder & CEO
AI Tools For WordPress Creators
Code, learn, troubleshoot, and secure WordPress sites with the CodeWP platform and our custom AI.
Start for Free
Contents

WordPress is almost 20 years old, but the default user registration emails seem stuck in the 2000s. In this article, we'll take a look at how you can customize default WordPress emails without a plugin. The inspiration for this post came from setting up our own custom emails in WordPress without a plugin or WooCommerce to lean on.

Of course, there are several plugins to do this, but many are overly complex, expensive, and don't do everything we need them to.

To get started, let's take a look at the main emails and how they're handled.

When a user registers on a WordPress website, two emails are typically sent:

  1. New User Registration Email to the Administrator: This email is sent to the website administrator, informing them of the new user registration. The email usually contains the following information:
  • Subject: [Site Name] New User Registration
  • Message: New user registration on your site [Site Name]: Username: [New User's Username] Email: [New User's Email Address]
  1. Welcome Email to the New User: This email is sent to the new user to welcome them and provide them with their login credentials. The email generally includes the following details:
  • Subject: [Site Name] Your username and password
  • Message: Username: [New User's Username] To set your password, visit the following address: [Password Reset Link] [Login URL]

The first email can be exhilarating or annoying, depending on how many users register per day.

The second is the first impression to a new user. And the core email is definitely lacking in terms of design and content.

The good news is that there are a decent selection of hooks that we can use to change these emails around.

User Registration Admin Email

I typically disable the admin new user registration email with this snippet:

PHP
// Remove the original user registration admin email action
remove_action('register_new_user', 'wp_send_new_user_notifications');

// Add our custom action that does nothing for admin notifications
add_action('register_new_user', 'cwpai_send_new_user_notifications', 10, 2);

/**
 * Custom new user registration action that only sends the notification to the user
 *
 * @param int $user_id The user ID
 * @param string $notify The type of notification to send
 */
function cwpai_send_new_user_notifications($user_id, $notify = 'user') {
    wp_send_new_user_notifications($user_id, $notify);
}

My prompt needed to include context gathered from some StackOverflow articles. Unfortunately, it's not as easy as returning false for wp_new_user_notification_email_admin, as discussed here, and we need to be specific when prompting CodeWP, or we'll get the wrong code*

*(as of the publication of this article. Our models will soon be updated to understand this limitation, following the methodology mentioned in this Tweet).

If you still want the admin user registration message, you can also change the content and subject like so:

PHP
// Hook custom function to overwrite default WP new user notification email
add_filter('wp_new_user_notification_email', 'cwpai_custom_user_reg_admin_email', 10, 3);

function cwpai_custom_user_reg_admin_email($wp_new_user_notification_email, $user, $blogname) {
    // Poem for new user notification email
    $poem = "A new user has arisen with grace,
Their journey on {$blogname} will they embrace,
Their username: {$user->user_login},
To check and assist them, do not hesitate";

    // Set the message, subject and headers for the email
    $wp_new_user_notification_email['message'] = $poem;
    $wp_new_user_notification_email['subject'] = "A poetical new user notification from {$blogname}";
    $wp_new_user_notification_email['headers'] = 'Content-Type: text/plain; charset=UTF-8';

    return $wp_new_user_notification_email;
}

My prompt on CodeWP was "Change User Registration Admin Email message to be a poem", but you can change the content to whatever you'd like, and override it using the following:

PHP
$wp_new_user_notification_email['message'] = $poem;

When the user sets their password for the first time, admins also get an email, which can very quickly clog an inbox. You can disable the notification using this snippet:

PHP
add_filter('retrieve_password_message', 'cwpai_disable_user_password_reset_admin_email', 10, 4);

function cwpai_disable_user_password_reset_admin_email($message, $key, $user_login, $user_data) {
    if (is_object($user_data) && isset($user_data->roles) && is_array($user_data->roles) && in_array('administrator', $user_data->roles)) {
        return '';
    }

    return $message;
}

Welcome Email to the New User

Now, let's play with the initial email sent to the user when they register on a WordPress site. In my opinion, it's a terrible first impression.

I asked CodeWP to do the following:

Using wp_new_user_notification_email do the following:

  • Make the message a good looking HTML template, and make the content more exciting.
  • Make the set password link a button, background of Instagram gradient, and add tiny text link if the button doesn't work.
  • Include bullet points about saving blog posts, following users, and getting email updates now that they're registered. Start each point with an emoji.
  • Make a header that links to the site homepage and uses the image ID 17 from media library. Image height should be max of 50px. Make this an actual image element.
  • Make the background #f7f7f7, but the content background white with a subtle border.

From that prompt, I got the following generation:

PHP
/**
 * Customize welcome email for new users in WordPress.
 */
function cwpai_custom_new_user_email( $wp_new_user_notification_email, $user, $blogname ) {

    // Set email background, border, and font colors
    $email_style = "style='background-color:#f7f7f7;border-radius:6px;border:1px solid #ccc;color:#333;'";
    $content_style = "style='background-color:#fff;padding:20px;border-radius:4px;border:1px solid #ddd;margin:10px 0;'";
    $link_style = "style='background-color:#de3d83;border-radius:3px;color:#fff;display:inline-block;font-size:14px;font-weight:bold;margin-top:20px;padding:12px 20px;text-decoration:none;text-transform:uppercase;'";
    $small_style = "style='display:inline-block;font-size:14px;margin-top:20px;padding-left:20px;text-decoration:none;'";

    // Create message content
    $message = "<div $content_style>";
    $message .= "<h2>" . sprintf( __( 'Welcome to %s!' ), $blogname ) . "</h2>";
    $message .= "<p>" . __( 'We are excited to have you join our community of bloggers! By creating an account on our site, you can access all of our premium content, save your favorite blog posts, follow other users, and receive email updates about new content.' ) . "</p>";
    $message .= "<h3>" . __( 'Benefits of Registration' ) . "</h3>";
    $message .= "<ul><li>" . __( 'Save blog posts' ) . "</li><li>" . __( 'Follow other users' ) . "</li><li>" . __( 'Receive email updates' ) . "</li></ul>";
    $message .= "<p>" . __( 'To get started, click the button below to set your password.' ) . "</p>";
    $message .= "<a $link_style href='" . network_site_url( "wp-login.php?action=rp&key=$user->user_activation_key&login=" . rawurlencode( $user->user_login ), 'login' ) . "'>" . __( 'Set Your Password' ) . "</a>";
    $message .= "<a $small_style href='" . network_site_url( "wp-login.php?action=rp&key=$user->user_activation_key&login=" . rawurlencode( $user->user_login ), 'login' ) . "'>" . __( 'If the button above doesn\'t work for you, use this link.' ) . "</a>";
    $message .= "</div>";

    // Create header image
    $header = "<a href='" . home_url() . "'><img src='" . wp_get_attachment_image_src( 17, 'full' )[0] . "' height='50' alt='" . $blogname . "'></a>";

    // Set email parameters
    $to = $user->user_email;
    $subject = sprintf( __( 'Welcome to %s!' ), $blogname );
    $headers = array( 'Content-Type: text/html; charset=UTF-8' );
    $message = $header . $message;

    // Apply email text domain and send email
    $wp_new_user_notification_email['message'] = apply_filters( 'cwpai_email', $message );
    $wp_new_user_notification_email['subject'] = apply_filters( 'cwpai_email', $subject );
    $wp_new_user_notification_email['headers'] = apply_filters( 'cwpai_email_headers', $headers );

    return $wp_new_user_notification_email;
}

add_filter( 'wp_new_user_notification_email', 'cwpai_custom_new_user_email', 10, 3 );

Which makes the new user email look awesome:

Conditional Content In Welcome Emails

CodeWP itself uses WordPress for the frontend. We use Nextend Social Login to offer social login. A few months ago, we noticed a problem - the default email would prompt users to set their password, EVEN if they used a social (passwordless) login method.

Using CodeWP itself, we created a helper function to check if the registered user was using a social provider, or a normal login:

PHP
function cwpai_social_linked($user_id = null)
{
    if (!$user_id) {
        $user_id = get_current_user_id();
    }

    global $wpdb;
    $table_name = $wpdb->prefix . 'social_users';
    $sql = "SELECT ID,type FROM $table_name WHERE ID = $user_id";
    $results = $wpdb->get_results($sql);

    $connected_account = $results[0]->type;
    if ($connected_account) {
        return $connected_account;
    } else {
        return false;
    }
}

And we use this within the following function to send a custom message, based on conditionals.

PHP
add_filter('wp_new_user_notification_email', 'cwpai_custom_welcome_email', 10, 3);

function cwpai_custom_welcome_email($wp_new_user_notification_email, $user, $blogname)
{
    // Check if social linked is blank or not
    if (cwpai_social_linked($user->ID) != '') {
        // Send different message for users with social linked

        $provider = cwpai_social_linked($user->ID);
        if ($provider == 'facebook') {
            $provider = 'Facebook';
        }

        $wp_new_user_notification_email['message'] = sprintf(
          //custom message goes here for social login
        );

        // Set custom email subject for users with social linked
        $wp_new_user_notification_email['subject'] = sprintf('Welcome to CodeWP', $blogname);
    } else {
        // Send default message for other users
        $reset_key = get_password_reset_key($user);
        $wp_new_user_notification_email['message'] = sprintf(
          //custom message goes here for regular login
        );
        // Set custom email subject for other users
        $wp_new_user_notification_email['subject'] = sprintf('[ACTIVATE] Confirm your registration with CodeWP', $blogname);
    }

    return $wp_new_user_notification_email;
}

You can do the same, using basic PHP if, else, elseif conditionals, sending custom registration messages to specific user groups, roles, meta, etc...

Changing Reply-To Email Address (and other headers)

There are situations where you may need to use noreply email addresses or configure a different email address for users to respond to, other than the one from which the message was sent.

Reply-to email addresses are set via the header of the message.

PHP
/**
 * Changes the reply-to email address for wp_new_user_notification_email function
 * to "john@smith.com"
 */
function cwpai_change_notification_email_address( $wp_new_user_notification_email, $user, $blogname ) {
	$wp_new_user_notification_email['headers'] .= 'Reply-To: John Smith <john@smith.com>' . "rn";
	return $wp_new_user_notification_email;
}
add_filter( 'wp_new_user_notification_email', 'cwpai_change_notification_email_address', 10, 3 );

Note: Use SMTP Plugin (and service)

As a note, it's not usually a good idea to send emails directly from your server. Instead, you should use a dedicated service for this, as there's less of a chance you can burn your domain or end up in spam.

My suggested "email stack" for WordPress is Mailersend and FluentSMTP. We use these providers for every WordPress project, including CodeWP!

Conclusion

In conclusion, customizing default WordPress emails without a plugin is not only possible but also relatively straightforward. With the right code snippets and hooks, you can easily modify the content and design of the emails sent by your WordPress site to users and administrators.

By using the provided code examples, you can disable or modify admin emails, create attractive welcome emails for new users, conditionally send custom messages to specific user groups, and change reply-to email addresses.

Additionally, it's essential to use an SMTP plugin and a dedicated email service to ensure the best deliverability and protect your domain from being flagged as spam.

Customizing your WordPress emails can enhance user experience, improve engagement, and help you make a better first impression on new users. With a little bit of effort and some code snippets, you can achieve a more professional and polished email communication system for your WordPress site.

About The Author
James LePage
Founder & CEO
More By James LePage
James LePage is an entrepreneur and founder of CodeWP, an AI platform for WordPress creators. With nearly a decade of experience founding startups and leading development agencies, James is focused on leveraging AI research and natural language processing to build smart solutions that make WordPress website creation efficient. As founder of CodeWP, James is dedicated to eliminating tedious developer searches and expensive hiring so anyone can build complex WordPress solutions easily. His technical expertise and passion for innovation drive CodeWP’s mission to serve WordPress creators globally with advanced AI capabilities.
More

More Reading

Make WordPress Easy With AI
© WPAI, Inc. 2024 | d.b.a CodeWP