Skip to main content
Login Join
Snippet · PHP

Rename WordPress Login Page

Shared by Adnan Limdiwala · May 25, 2026

1 copy
26 views
1 upvote
Back to Snippets

Here’s a clean snippet you can add to your functions.php or use as a must-use plugin:

Here’s what each part does:

# Hook Purpose
1 init + add_rewrite_rule Registers /wacc-admin as a valid route pointing to wp-login.php internally
2 register_activation_hook Flushes rewrite rules once when activated so the slug works immediately
3 init + URI check Blocks direct access to /wp-login.php and returns a 404 — hides the default login from bots
4 login_url filter Replaces all wp_login_url() calls site-wide so WP always generates /wacc-admin links
5 login_redirect filter Sends admins to the dashboard and other users to the homepage after login
6 register_deactivation_hook Cleans up rewrite rules if you ever remove the snippet

 

Please update your permalink after adding this code.

/**
 * Rename WordPress Login Page to /wacc-admin
 *
 * HOW TO USE:
 *   Option A) Paste into your theme's functions.php
 *   Option B) Save this file as /wp-content/mu-plugins/rename-login-page.php
 *
 * After adding, visit: https://yoursite.com/wacc-admin
 * The default /wp-login.php will redirect to 404 for security.
 */


// 1. REGISTER THE CUSTOM LOGIN SLUG ================================
add_action( 'init', 'pcm_register_custom_login_slug' );
function pcm_register_custom_login_slug() {
    add_rewrite_rule( '^wacc-admin/?$', 'wp-login.php', 'top' );
    add_rewrite_tag( '%wacc_login%', '([^&]+)' );
}


// 2. FLUSH REWRITE RULES ON ACTIVATION (run once) ==================
register_activation_hook( __FILE__, function() {
    pcm_register_custom_login_slug();
    flush_rewrite_rules();
});


// 3. REDIRECT /wp-login.php TO 404 (blocks default login URL) ======
add_action( 'init', 'pcm_block_default_login_page' );
function pcm_block_default_login_page() {

    // Allow legitimate internal WP login actions to pass through
    $allowed_actions = [ 'postpass', 'logout', 'lostpassword', 'retrievepassword', 'resetpass', 'rp', 'register', 'confirmaction' ];

    $action         = isset( $_REQUEST['action'] ) ? sanitize_key( $_REQUEST['action'] ) : '';
    $is_interim     = isset( $_REQUEST['interim-login'] );
    $requested_uri  = isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '';

    // Detect direct access to wp-login.php (not via our slug)
    if ( strpos( $requested_uri, 'wp-login.php' ) !== false ) {

        // Allow WP Cron, AJAX, and admin bar requests through
        if ( defined('DOING_CRON') && DOING_CRON ) return;
        if ( defined('DOING_AJAX') && DOING_AJAX ) return;

        // Allow whitelisted actions (logout, password reset, etc.)
        if ( in_array( $action, $allowed_actions, true ) ) return;
        if ( $is_interim ) return;

        // Block everything else — return a 404
        wp_die( '<h2>Not Found</h2><p>The page you are looking for could not be found.</p>', '404 Not Found', [ 'response' => 404 ] );
    }
}


// 4. REPLACE ALL LOGIN URLs IN WP WITH THE CUSTOM SLUG =============
add_filter( 'login_url', 'pcm_custom_login_url', 10, 3 );
function pcm_custom_login_url( $login_url, $redirect, $force_reauth ) {
    $custom_url = home_url( 'wacc-admin' );

    if ( ! empty( $redirect ) ) {
        $custom_url = add_query_arg( 'redirect_to', urlencode( $redirect ), $custom_url );
    }
    if ( $force_reauth ) {
        $custom_url = add_query_arg( 'reauth', '1', $custom_url );
    }

    return $custom_url;
}


// 5. FIX THE REDIRECT AFTER SUCCESSFUL LOGIN =======================
add_filter( 'login_redirect', 'pcm_login_redirect', 10, 3 );
function pcm_login_redirect( $redirect_to, $requested_redirect_to, $user ) {
    // Redirect admins to dashboard, others to home (customize as needed)
    if ( isset( $user->roles ) && is_array( $user->roles ) ) {
        if ( in_array( 'administrator', $user->roles, true ) ) {
            return admin_url();
        }
    }
    return $redirect_to ?: home_url();
}


// 6. FLUSH REWRITE RULES ON DEACTIVATION ===========================
register_deactivation_hook( __FILE__, function() {
    flush_rewrite_rules();
});
Know a different way to do this? Add your approach as a variation so folks can compare them side by side.
Submit a variation

0 comments