Hey there! You're using an out-of-date browser, so this site probably looks pretty funny. Upgrade your browser for the full experience.

Custom WordPress Welcome Emails

The default WordPress “new user registration” email is boring, but it doesn’t have to be!

The default “new user registration” email

Anyone who’s developed for (or used) WordPress knows that you get a pretty basic email when you register as a new user.

It includes your login name, a link to set your password, and that’s it. Not very exciting. To top it all off, the contents of that email are hard-coded in the WordPress core so you can’t customize it using a template.

But, fear not! It’s a little roundabout, but it is possible to customize it with some code in your functions.php.

The wp_mail filter is your friend

The wp_mail filter runs every time WordPress sends an email. It also lets you modify those emails as they come through.

Knowing this, we can easily update the content of our new “new user registration” email.

The above code checks the subject of the email being sent to see if it’s a new-user email (usually in the form Welcome to SITENAME). If it matches, we create a new email with an updated message.

The $args parameter looks something like:

In our case, we use the existing to, subject, headers, and attachments values and only change the body of the message itself.

That’s the simple case. Pretty easy, right?

Now let’s level-up a bit.

Adding a password reset link

The password reset link is a nice touch in the built-in email. The new user can click the link, set their initial password, and they’re off and running.

Our email doesn’t have a password reset link, so let’s add one!

There are a few new steps here so let’s go through them:

Get the newly-created user

At the point that wp_mail is called, the user registration has happened so the user exists in the database.

We can get their email address from $email = $args['to'][0] and then get the user object by calling $user = get_user_by('email', $email);.

Create a new user_activation_key

All new users have a user_activation_key set in the database (which is part of the url the built-in email sends out). But the database value is hashed so we don’t know what it is and can’t include it in our email.

That means we have to create our own and store it back to the database:

$key = wp_generate_password(20, false);
require_once(ABSPATH . WPINC . '/class-phpass.php');
$hasher = new PasswordHash(8, true);
$hashed = time() . ':' . $hasher->HashPassword($key);
$wpdb->update($wpdb->users, ['user_activation_key' => $hashed], ['user_login' => $user->user_login]);

The value of $key is what we include in the url while $hashed is the hashed value that gets saved to the database.

Craft the reset link

Now we can build the password reset link and include it in our email:
$regUrl = network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user->user_login), 'login');

Personalizing our email

Wouldn’t it be nice to greet our new user by name? You can, but this is where it gets a little tricky.

As you may know, a user’s first and last name are stored as part of the user_meta data.

There’s one small problem though. That user metadata hasn’t been set at the point that the “new user registration” email comes through!

That means we have to figure out the user’s name before the email is sent, which is where the user_register action comes in.

If we handle user_register, all of the values submitted from the registration form will be accessible in $_POST.

In the above code, we just loop over $_POST and manually set each value to user_meta for the user.

Now, back in wp_mail, we can retrieve the user metadata with $userMeta = get_user_meta($user->ID); which lets us add the user’s name to our email:

Sit back and enjoy your custom email

If you were feeling ambitious, all of the above could be wrapped in a plugin which allowed an admin to customize the email through the WordPress admin settings.

But, even if you don’t, you now have a custom “new user registration” email that is easy to maintain as part of your theme!