How to Stop Elementor Pro Login Redirecting to /wp-admin on Error
So you might have faced this problem like many other people who, upon using the Elementor Pro login widget on the login page, if you enter the wrong login credentials, Elementor Pro will redirect you to /wp-admin page, which is the default login page by WordPress. And trust me, this looks so unprofessional and does not leave a good impact on customers.
In this tutorial, I’ll show you how to prevent the Elementor Pro login page from redirecting to the WordPress default login page when incorrect login credentials are entered. And its solution is quite simple. Below is step by step-by-step process on how to resolve this quickly.
Step 1: Paste this code in functions.php
You can find function.php in the following path. Simply go to Appearance>> Theme Editor >> Function.php

(Prefer a child theme or the Code Snippets plugin to keep changes update-safe.)
If your login page slug isn’t
/login/
, change the$login_slug
below accordingly.
<?php
/**
* Elementor Pro login: keep users on the same page and show a clean notice.
* Works with an Elementor page at /login/ (change $login_slug if different).
*/
add_action('init', function () {
// Change this if your login page slug is different, e.g. 'sign-in'
if (!defined('LMSC_LOGIN_SLUG')) {
define('LMSC_LOGIN_SLUG', 'login');
}
});
/**
* 1) Wrong credentials: after WordPress fails auth, return to the Elementor page
* with ?login=failed so our shortcode can show an inline message.
*/
add_action('wp_login_failed', function ($username) {
$ref = wp_get_referer();
$slug = '/' . trim(LMSC_LOGIN_SLUG, '/');
if ($ref && strpos($ref, $slug) !== false) {
wp_safe_redirect(add_query_arg('login', 'failed', $ref));
exit;
}
});
/**
* 2) Empty fields: if username or password is empty, send user back with ?login=empty.
* Priority 1 so it runs before core auth; avoid AJAX calls.
*/
add_filter('authenticate', function ($user, $username, $password) {
if (wp_doing_ajax()) return $user;
if ($username === '' || $password === '') {
$ref = wp_get_referer();
$slug = '/' . trim(LMSC_LOGIN_SLUG, '/');
if ($ref && strpos($ref, $slug) !== false) {
wp_safe_redirect(add_query_arg('login', 'empty', $ref));
exit;
}
// Optional fallback if no referrer (uncomment & set your page):
// wp_safe_redirect(home_url('/' . LMSC_LOGIN_SLUG . '/?login=empty')); exit;
}
return $user;
}, 1, 3);
/**
* 3) Shortcode to print a friendly message based on ?login= flag.
* Use [login_notice] on your Elementor page (alias: [login_failed_notice]).
*/
function lmsc_login_notice_cb() {
if (!isset($_GET['login'])) return '';
$status = sanitize_key($_GET['login']);
$messages = [
'failed' => 'Incorrect username or password. Please try again.',
'empty' => 'Both username and password are required.',
'loggedout' => 'You have been logged out successfully.',
'expired' => 'Your session expired. Please log in again.',
'checkemail'=> 'Check your email for the reset link.',
'registration' => 'Registration complete. Please log in.'
];
if (!isset($messages[$status])) return '';
return '<div class="elementor-message elementor-message-danger" role="alert" style="margin-bottom:12px;">'
. esc_html($messages[$status])
. '</div>';
}
add_shortcode('login_notice', 'lmsc_login_notice_cb');
// Back-compat with your earlier shortcode name:
add_shortcode('login_failed_notice', 'lmsc_login_notice_cb');
Step 2: Paste this on your Elementor Login page
On the same page where your Elementor Pro Login widget lives:
- Add a Shortcode widget above the login form.
- Paste this shortcode:

[login_notice]
You can also edit the failed notice message. Search this line in the code you pasted in function.php and replace with your own line.
Incorrect username or password. Please try again.or Visit Contact us page.
Step 3: Safely redirect direct visits to wp-login.php
→ /login/
This replaces any older
init
+$pagenow == 'wp-login.php'
snippet, which breaks the?login=failed
flag and hides your on-page message.
/**
* Redirect only direct GET hits to wp-login.php to your pretty login page.
* Does NOT intercept POST (real login attempts), so your on-page notices keep working.
*/
add_action('login_init', function () {
// Let POST requests through (needed for actual authentication)
if (isset($_SERVER['REQUEST_METHOD']) && strtoupper($_SERVER['REQUEST_METHOD']) !== 'GET') {
return;
}
// Allow special core actions to function normally (logout/reset, etc.)
$action = isset($_REQUEST['action']) ? sanitize_key($_REQUEST['action']) : 'login';
$allow = ['logout','lostpassword','retrievepassword','rp','resetpass','postpass','confirm_admin_email','interim-login'];
if (in_array($action, $allow, true) || isset($_REQUEST['interim-login'])) {
return;
}
// Preserve a few friendly messages (optional)
$args = [];
foreach (['loggedout','checkemail','registration'] as $k) {
if (isset($_GET[$k])) {
$args[$k] = sanitize_text_field(wp_unslash($_GET[$k]));
}
}
wp_safe_redirect(add_query_arg($args, home_url('/' . LMSC_LOGIN_SLUG . '/')));
exit;
});
Remove any previous snippet like:
add_action('init', function () {
global $pagenow;
if (!is_user_logged_in() && $pagenow === 'wp-login.php') { wp_safe_redirect(home_url('/login/')); exit; }
});
It fires too early and swallows the ?login=failed
flag—your shortcode won’t show the message.
That’s all. Now, when a user enters a wrong password or leaves fields empty, they stay on your beautifully designed Elementor page and see a clear inline message no /wp-admin
detour.
🚀 Still unsure how to get a high-converting landing page?
At LMS Crafter, we design & build Elementor landing pages that load fast, look stunning, and convert.
👉 Book a free strategy call and let’s plan your page today!
This is great, but how can I integrate a redirect for wp-login.php to my login page “/login/”?
I had this code, but it seems to intercept your redirect back to /login with the error. It will send the user back to the /login page when there is an error, but the shortcode no longer outputs anything so whatever was getting passed is now lost.
// Disable wp login
function custom_login_page() {
global $pagenow;
if ( ! is_user_logged_in() && $pagenow == ‘wp-login.php’ ) {
wp_safe_redirect( home_url().’/login/’ );
exit;
}
}
if(!is_user_logged_in()) {
add_action(‘init’,’custom_login_page’);
}
Hey Chris, great question!
Your init + $pagenow === ‘wp-login.php’ redirect fires too early and swallows the ?login=failed flag, so the shortcode can’t print the message.
I’ve updated the article with a safer redirect that only catches direct GET visits to wp-login.php and leaves real login POSTs alone (so the error flag still reaches the login page).
Use this instead:
// Redirect direct GET hits to wp-login.php → /login/ (doesn’t break inline errors)
add_action(‘login_init’, function () {
// Let POST requests (actual auth) pass through
if (isset($_SERVER[‘REQUEST_METHOD’]) && strtoupper($_SERVER[‘REQUEST_METHOD’]) !== ‘GET’) return;
// Allow special core actions (logout/reset/etc.)
$action = isset($_REQUEST[‘action’]) ? sanitize_key($_REQUEST[‘action’]) : ‘login’;
$allow = [‘logout’,’lostpassword’,’retrievepassword’,’rp’,’resetpass’,’postpass’,’confirm_admin_email’,’interim-login’];
if (in_array($action, $allow, true) || isset($_REQUEST[‘interim-login’])) return;
// Optional: preserve friendly messages
$args = [];
foreach ([‘loggedout’,’checkemail’,’registration’] as $k) {
if (isset($_GET[$k])) $args[$k] = sanitize_text_field(wp_unslash($_GET[$k]));
}
wp_safe_redirect(add_query_arg($args, home_url(‘/login/’)));
exit;
});
Why this works
Doesn’t intercept POST logins → ?login=failed still gets added by the other snippet.
Lost-password/logout screens keep working.
Your [login_notice] (or [login_failed_notice]) shows the message on /login/.
Quick test: clear cache → submit a wrong password on /login/ → you should stay on /login/?login=failed and see the inline error.
If your login page isn’t /login/, just change that path in the snippet
Works perfectly! Thank you!!