Customize WordPress User Approval Emails Without Plugins (Step-by-Step Guide)

Customizing WordPress user approval emails without plugins involves using WordPress’s built-in filter hooks. This allows you to modify the subject, message, and headers of the emails sent to both the user and the administrator when a new user registers and is awaiting approval, or when their account is approved or denied.

Important Note: Before making any changes to your theme’s functions.php file, it’s highly recommended to:

  • Create a Child Theme: This ensures your customizations aren’t overwritten when you update your main theme.
  • Backup Your Website: Always back up your site files and database before making direct code edits.
  • Use a Code Snippets Plugin (Optional but Recommended for Beginners): While this guide focuses on “without plugins,” a plugin like “Code Snippets” can provide a safer environment for adding custom code without directly editing functions.php.

Understanding the Core Concept: Filters

WordPress uses “filters” to allow developers to modify data before it’s used or displayed. When an email is about to be sent, WordPress “applies” a filter to its content, subject, or headers. You can “hook” into these filters with your own custom functions to change the default values.

Scenario: User Approval Process

For user approval, you’ll likely encounter a few different email types:

  1. Email to the Administrator: When a new user registers and requires approval.
  2. Email to the User (Pending Approval): Notifying the user that their account is awaiting review.
  3. Email to the User (Approved): Notifying the user that their account has been approved.
  4. Email to the User (Denied): Notifying the user that their account has been denied.

Step-by-Step Guide

To customize these emails, you’ll add code to your child theme’s functions.php file.

Accessing functions.php:

  1. Log in to your WordPress admin dashboard.
  2. Navigate to Appearance > Theme File Editor.
  3. On the right-hand side, select your child theme (if you’re using one).
  4. Locate and click on functions.php.

General Email Customization Filters (for built-in WordPress new user notifications):

While these don’t specifically cover “user approval” in the sense of a pending/approved/denied flow (which often requires a plugin or custom code to implement), they are fundamental for new user notifications:

  • wp_new_user_notification_email: Filters the entire email array (to, subject, message, headers) sent to the new user.
  • wp_new_user_notification_email_admin: Filters the entire email array sent to the admin for a new user registration.

Example 1: Customizing the New User Notification Email to the User

This is the email a user receives right after registration. If you’re implementing user approval, you’d likely want to change this to say their account is “pending.”

<?php
/**
 * Customize the new user notification email sent to the user.
 *
 * @param array $email_args Used to build wp_mail().
 * @param WP_User $user User object for new user.
 * @param string $blogname The site title.
 * @return array Modified email arguments.
 */
function custom_new_user_pending_email( $email_args, $user, $blogname ) {
    $email_args['subject'] = sprintf( __('Your Registration for %s is Pending Approval', 'your-text-domain'), $blogname );
    $email_args['message'] = sprintf(
        __("Hi %s,\n\nThank you for registering on %s. Your account is currently under review and will be activated shortly after approval.\n\nWe will send you another email once your account has been approved.\n\nBest regards,\nThe %s Team", 'your-text-domain'),
        $user->user_login,
        $blogname,
        $blogname
    );
    // You can also modify headers if needed, e.g., $email_args['headers']
    return $email_args;
}
add_filter( 'wp_new_user_notification_email', 'custom_new_user_pending_email', 10, 3 );

Example 2: Customizing the New User Notification Email to the Admin

This email is sent to the site administrator when a new user registers. You might want to include a direct link to approve/deny the user if you have a custom user approval system.

<?php
/**
 * Customize the new user notification email sent to the admin.
 *
 * @param array $email_args Used to build wp_mail().
 * @param WP_User $user User object for new user.
 * @param string $blogname The site title.
 * @return array Modified email arguments.
 */
function custom_new_user_admin_notification_email( $email_args, $user, $blogname ) {
    $email_args['subject'] = sprintf( __('New User Registration Awaiting Approval on %s', 'your-text-domain'), $blogname );
    $admin_url = admin_url( 'users.php?s=' . $user->user_login . '&new_user_approve_filter=pending&paged=1' ); // Example for a plugin-based approval system link. Adjust if your custom system has a specific URL.
    $email_args['message'] = sprintf(
        __("A new user, %s (%s), has registered on your site %s and is awaiting approval.\n\nUser Details:\nUsername: %s\nEmail: %s\n\nTo review and approve/deny this user, please visit: %s\n\nBest regards,\nYour WordPress Site", 'your-text-domain'),
        $user->user_login,
        $user->user_email,
        $blogname,
        $user->user_login,
        $user->user_email,
        $admin_url
    );
    return $email_args;
}
add_filter( 'wp_new_user_notification_email_admin', 'custom_new_user_admin_notification_email', 10, 3 );

Customizing Approval/Denial Emails (Requires Custom Logic or a Plugin’s Filters)

If you’re building a user approval system from scratch or relying on a plugin that provides hooks for approval/denial, you’ll need to identify those specific hooks. Without a plugin, you’d have to write the entire user approval/denial logic yourself, including when and how to send these emails.

Let’s assume you’ve implemented a custom user approval system, and you have functions like send_user_approved_email() and send_user_denied_email() that use wp_mail(). You could then apply filters to those emails.

General approach for custom approval/denial emails (conceptual):

If you have custom code that sends emails upon approval or denial, you’d typically have a function that constructs and sends the email. Within that function, you’d use apply_filters to make it customizable.

For example, if you had a function my_custom_send_approved_email($user_id):

<?php
function my_custom_send_approved_email( $user_id ) {
    $user = get_userdata( $user_id );
    $blogname = get_option( 'blogname' );

    $subject = sprintf( __('Your Account on %s Has Been Approved!', 'your-text-domain'), $blogname );
    $message = sprintf(
        __("Hi %s,\n\nGood news! Your account on %s has been approved and is now active.\n\nYou can now log in here: %s\n\nWe look forward to seeing you around!\n\nBest regards,\nThe %s Team", 'your-text-domain'),
        $user->user_login,
        $blogname,
        wp_login_url(), // Link to the login page
        $blogname
    );
    $headers = array( 'Content-Type: text/html; charset=UTF-8' ); // Example header

    // Apply filters for customization
    $email_data = apply_filters( 'my_custom_user_approved_email_data', array(
        'to'      => $user->user_email,
        'subject' => $subject,
        'message' => $message,
        'headers' => $headers,
    ), $user, $blogname );

    wp_mail( $email_data['to'], $email_data['subject'], $email_data['message'], $email_data['headers'] );
}

// Now, to customize this email, you'd use the filter 'my_custom_user_approved_email_data'
add_filter( 'my_custom_user_approved_email_data', 'customize_my_approved_email', 10, 3 );

function customize_my_approved_email( $email_data, $user, $blogname ) {
    // Change subject
    $email_data['subject'] = 'Welcome to our Community, ' . $user->user_login . '!';

    // Change message
    $email_data['message'] = "<h1>Congratulations, {$user->user_login}!</h1><p>Your registration on {$blogname} is now complete.</p><p>You can access your account and start exploring here: <a href='" . wp_login_url() . "'>Login Now!</a></p><p>If you have any questions, feel free to reply to this email.</p>";

    // Add or modify headers
    $email_data['headers'][] = 'Bcc: admin@yourdomain.com'; // Send a BCC to admin

    return $email_data;
}

// Similarly for denied email:
function my_custom_send_denied_email( $user_id, $reason = '' ) {
    $user = get_userdata( $user_id );
    $blogname = get_option( 'blogname' );

    $subject = sprintf( __('Regarding Your Registration on %s', 'your-text-domain'), $blogname );
    $message = sprintf(
        __("Hi %s,\n\nWe regret to inform you that your registration on %s has been denied.", 'your-text-domain'),
        $user->user_login,
        $blogname
    );
    if ( ! empty( $reason ) ) {
        $message .= "\n\nReason: " . $reason;
    }
    $message .= "\n\nIf you believe this is a mistake, please contact us.\n\nBest regards,\nThe %s Team";
    $message = sprintf( $message, $blogname );
    $headers = array( 'Content-Type: text/plain; charset=UTF-8' );

    $email_data = apply_filters( 'my_custom_user_denied_email_data', array(
        'to'      => $user->user_email,
        'subject' => $subject,
        'message' => $message,
        'headers' => $headers,
    ), $user, $blogname, $reason );

    wp_mail( $email_data['to'], $email_data['subject'], $email_data['message'], $email_data['headers'] );
}

// And its customization filter:
add_filter( 'my_custom_user_denied_email_data', 'customize_my_denied_email', 10, 4 );

function customize_my_denied_email( $email_data, $user, $blogname, $reason ) {
    $email_data['subject'] = 'Important: Your Account Application for ' . $blogname;
    $email_data['message'] = "Dear {$user->user_login},\n\nWe appreciate your interest in {$blogname}. Unfortunately, we are unable to approve your account at this time.";
    if ( ! empty( $reason ) ) {
        $email_data['message'] .= "\n\nReason for denial: " . $reason;
    }
    $email_data['message'] .= "\n\nIf you have any questions, please visit our contact page.\n\nThank you,\n" . $blogname . " Support";
    return $email_data;
}

Placeholders and Dynamic Content:

In your email messages, you can use placeholders to insert dynamic content:

  • %s: Used with sprintf() to insert strings like the username, blog name, or email.
  • $user->user_login: The username.
  • $user->user_email: The user’s email address.
  • get_option('blogname'): Your site’s title.
  • wp_login_url(): The URL to your WordPress login page.
  • admin_url('users.php'): Base URL for the admin users page.

Tips for Writing Email Content:

  • Plain Text vs. HTML: By default, WordPress emails are plain text. If you want to use HTML (for better formatting, links, etc.), you’ll need to set the Content-Type header to text/html.
$email_args['headers'] = array( 'Content-Type: text/html; charset=UTF-8' );
  • Conciseness: Keep your emails clear and to the point.
  • Call to Action: Guide the user on what to do next (e.g., “log in,” “check back later”).
  • Branding: Incorporate your site’s name and a consistent tone.
  • Testing: Always send test emails to ensure they look as expected and are delivered. You can use a plugin like WP Mail SMTP to ensure deliverability and log emails.

By following these steps and using the provided code examples as a starting point, you can effectively customize your WordPress user approval emails without relying on additional plugins. Remember to always work within a child theme and back up your site!

Related Posts


How to Retrieve and Expose Gutenberg & Theme-Generated CSS in WordPress

If you want to extract the CSS generated by Gutenberg and your WordPress theme, you can do so using ...

Fix SEO Issues: Add Trailing Slash to Category URLs Easily

To fix SEO issues by consistently adding a trailing slash to your category URLs in WordPress, the ea...

wp-cron events stopped working and are showing next run in the past

It sounds like your WordPress cron jobs (wp-cron.php) are not firing correctly, which is a common is...

Why does wpcf7_mail_sent not detect logged-in user context in WordPress?

The wpcf7_mail_sent hook in Contact Form 7 fires after the email has been successfully sent. The rea...

Recent Posts