Do you want to show your users a custom login page?
By choosing a custom page, users can log in to the WordPress dashboard using the page you have set as default.
Creating a custom login page for WordPress isn’t a tough task.
In this updated tutorial, I will walk you through the code by which you can create a simple login form for your users.
Also, the previous code I used was deprecated, so there was a need to update this post. The code I will present to you is fully compatible with the latest version of WordPress.
Why You Need Custom Login Page
Of course, there are various reasons for it.
Few of us don’t like the default WordPress login page due to its interface or copyright links. Many of us would like to send the user to a different page where the user can log in to the website without accessing the main default login page.
If you want to create a front-end login page for WordPress, this tutorial will surely help you.
Remember, I didn’t style this login page because different people have different opinions. So you have to style it manually as per your needs. Also, you don’t need to be good at designing.
If you know CSS you are good to go.
You can use this code for any website. Few tweaks to code will take this login form to the next level.
Another reason for using the custom login page is that if you have a membership site, then you need one. So you can easily create a client login page in WordPress.
Creating a User Login Page in WordPress
This tutorial is all about creating a custom login page in WordPress; we will create a plugin.
We will create a few functions and a specific shortcode. In the previous version of this tutorial, we used the template system to show our login page in the front.
But, we will no longer use that. Instead, we will use shortcode.
You might ask why are you switching from template to shortcode?
I have a reason for this. When writing this tutorial, it is hard to create a template in the Block editor or so-called Gutenberg. Creating a template in Gutenberg is beyond the scope of this tutorial.
Creating a Plugin
Firstly, we will create a plugin and name it Custom Login
. Create a file and call it custom-login.php
.
Inside, paste this code.
<?php /** * Plugin Name: Custom Login * Description: This plugin lets you add the custom login feature on any post or page by using shortcodes. * Plugin URI: http://websiteguider.com * Author: WebsiteGuider * Author URI: http://websiteguider.com * Version: 1.0.0 * License: GPL2 * Text Domain: custom-login * */
I wouldn’t go into detail like what’s here going on. There are plenty of tutorials already on Google.
Adding some titbits to custom-login.php
Once the plugin is in the list in the backend, we can insert a few code lines to custom-login.php
. Put these lines of code after the plugin information.
/**
/** * Enqueue scripts * * == main.js == This file adds client side checking to our login and register pages. */ function custom_enqueue_scripts() { wp_enqueue_script( 'main-js', plugins_url() . '/custom-plugin/js/main.js', array( 'jquery' ), false, false ); } add_action( 'wp_enqueue_scripts', 'custom_enqueue_scripts' ); // Define constants so we can use them as shortcuts define("SHORTCODES_PATH", plugin_dir_path( __FILE__ ) . 'shortcodes'); define("FUNCTIONS_PATH", plugin_dir_path( __FILE__ ) . 'functions'); // Include the required Files require_once SHORTCODES_PATH . '/login-shortcode.php'; require_once FUNCTIONS_PATH . '/login-functions.php'; require_once FUNCTIONS_PATH . '/custom-login-functions.php';
Here we are adding a JavaScript file, few constants we will use later, and few files we require.
Creating our folders
To make the code easier to maintain, we will create three folders such as
- Shortcodes: Inside this, we will store our shortcode file.
- Functions: This folder will hold a few files related to custom functions.
- JS: All the JavaScript files will go inside this folder.
Creating files
Now we will start playing with code. Are you ready to get your hands dirty with code? Let’s begin.
Firstly, we will start with the Functions folder. Inside the Functions folder, create a file custom-login-functions.php
. Inside this file, put this code.
<?php /** * Log-in the User * * This function accepts various parameters that are used for checking whether the user exists or not. * * @since 1.0.0 * * @param int $user_id The ID of the user. * @param string $user_login The users username/email. * @param string $user_pass Password of the user. * @param boolean $user_remember Whether to remember the user credentials or not. * * @return void Return early if the user doesn't exist. * @author WebsiteGuider **/ function custom_log_userin($user_id, $user_login, $user_pass, $user_remember = false ) { if( ! absint( $user_id ) || $user_id < 1 ) { return; } wp_set_auth_cookie( $user_id, $user_remember ); wp_set_current_user( $user_id, $user_login ); do_action( 'wp_login', $user_login, get_userdata( $user_id ) ); } function custom_error_set( $id, $value ) { global $error_json; if( is_null($value) ) { unset($error_json); return; } $id = sanitize_key( $id ); if( is_array($value) ) { $error_json[ $id ] = wp_json_encode( $value ); } else { $error_json[ $id ] = esc_attr( $value ); } return $error_json; } function custom_error_get( $id ) { global $error_json; $maybe_decode_json = json_decode($error_json[ $id ]); if( ! is_null( $maybe_decode_json ) && ! is_array($maybe_decode_json) ) { $maybe_decode_json = json_decode($error_json[ $id ], true); } else { $maybe_decode_json = FALSE; } return $maybe_decode_json; } function custom_get_errors() { return custom_error_get('custom-errors'); } function custom_output_error($id, $value) { $errors = custom_get_errors(); if( ! $errors ) { $errors = array(); } $errors[ $id ] = $value; custom_error_set('custom-errors', $errors); } function custom_print_errors() { $errors = custom_get_errors(); if( ! empty($errors) ) { ?> <div class="custom-error"> <?php foreach( $errors as $error_id => $error ) { echo '<p class="error_' . $error_id .'"><strong>Error:</strong> ' . $error . '</p>'; } ?> </div> <?php } }
You can see there are six functions. But I will discuss custom_log_userin()
. I wouldn’t consider others because what they do is printing the error on the front login page.
Let’s come to our function, which is an essential function for creating a custom login page. This function logs the user in once he enters his/her Information. Inside this function, we first check for, $user_id
which should hold an absolute integer value. Otherwise, the code wouldn’t run.
After that, if the $user_id
meets our requirement, then the user is logged in.
Wait a minute, why would you user login if you haven’t checked the credentials yet? Don’t panic; we haven’t yet logged him in. We will use this function inside other functions where he will be able to log in.
Ok, let’s do that.
Create another file in the same folder and name it login-functions.php
. Copy and paste this code inside the file.
<?php /** * Generate the HTML markup of the form * * @since 1.0.0 * * @param string $custom_redirect The URL where the user should be redirected after submitting the form. * * @return void Return early if the user is logged in. * @author WebsiteGuider **/ function custom_html_login_form( $custom_redirect ) { if( ! is_user_logged_in() ) { ?> <form method="post" class="custom-login-form"> <style type="text/css"> .custom-error { margin-bottom: 10px; padding: 10px; background-color: #d64646; color: white; border-radius: 5px; } .custom-error p { margin: 0; } </style> <?php custom_print_errors(); ?> <p> <label for="custom-user"><?php _e('Username', 'custom-login-register'); ?></label> <input type="text" name="custom_user" id="custom-user" placeholder="Type Username or Email" /> </p> <p> <label for="custom-pass"><?php _e('Password', 'custom-login-register'); ?></label> <input type="password" name="custom_pass" id="custom-pass" placeholder="Type the password" /> </p> <p> <label for="remember-me"> <input type="checkbox" name="remember_me" id="remember-me"/> <?php _e('Remember Me', 'custom-login-register'); ?> </label> </p> <p> <a href="<?php echo wp_lostpassword_url(); ?>"><?php _e('Lost Password', 'custom-login-register'); ?></a> </p> <p> <input type="hidden" name="custom_login_nonce" value="<?php echo wp_create_nonce('custom-login-nonce'); ?>" /> <input type="hidden" name="custom_redirection" value="<?php echo esc_url( $custom_redirect ); ?>"/> <input type="submit" name="submit_custom_login" value="<?php _e('Login', 'custom-login-register'); ?>" /> </p> </form> <?php } else { _e("You are logged in", 'custom-login-register'); } } add_action( 'init', 'process_custom_login_form' ); /** * Process the Log-In form * * This callback function is called before any headers are sent. * With this function you can validate the user details submitted by him using our log-in form. * * @since 1.0.0 * * @return void * @author WebsiteGuider **/ function process_custom_login_form( ) { // Validate the username or email field before submitting if ( isset($_POST['custom_user'])) { $custom_user = trim($_POST['custom_user']); } // Validate password field before submitting if ( isset($_POST['custom_pass']) ) { $custom_pass = trim($_POST['custom_pass']); } if( wp_verify_nonce( (isset($_POST['custom_login_nonce']) ? $_POST['custom_login_nonce'] : ''), 'custom-login-nonce' ) ) { $user_info = get_user_by( 'login', $custom_user ); if( ! $user_info ) { $user_info = get_user_by( 'email', $custom_user ); } if( $user_info ) { $user_id = $user_info->ID; if( wp_check_password( $custom_pass, $user_info->user_pass, $user_id ) ) { if( isset($_POST['remember_me']) ) { $_POST['remember_me'] = true; } else { $_POST['remember_me'] = false; } custom_log_userin($user_id, $custom_user, $custom_pass, $_POST['remember_me']); wp_redirect($_POST['custom_redirection']); die; } else { custom_output_error('wrong_password', 'The password you entered is incorrect.'); } } else { custom_output_error('wrong_username', 'The username you entered is incorrect.'); } } }
You can notice two functions. The first one has HTML inside it, and the other has PHP code which does all the things of backend.
Our function custom_html_form()
also has a check, which is whether the current user is logged in or not. If he is already logged in, notifies him, else show the HTML form.
This function has one parameter $custom_redirect
. This parameter is used for redirecting the user after he successfully logs in. You can set this in a shortcode where we will use this functionality.
In my case, I will redirect the user to the home page, but you can send him directly to the admin page, which I will show you later on how to do that.
This function also uses other functions as well like custom_get_errors()
(shows an error if found), wp_lostpassword_url()
(lost password functionality), wp_create_nonce()
(for security purposes).
Now let’s come to another function. process_custom_login_form()
Processes our HTML form to the backend. It sends and receives data for verification.
To better understand this function, I created a simple mockup. I think this way you will understand it better.
We are near to conclusion, stay tuned.
Please create a new file inside the shortcode folder and name it login-shortcode.php
. Inside this file, put this code.
<?php /** * Shortcode for showing Sign In form. * * Use [custom_login] shortcode in page, post, or widget to display the log-in form. * * @since 1.0.0 * * @param array $atts The list of attributes passed when calling the shortcode. * * @return Return the login form using output buffering. * @author WebsiteGuider **/ function shortcode_custom_login( $atts ) { if(isset($atts['redirect'])) { $custom_redirect = $atts['redirect']; } if( empty($atts['redirect']) ) $custom_redirect = home_url(); // Start Output buffering ob_start(); // Output the HTML form here custom_html_login_form( $custom_redirect ); // End Output buffering by returning it return ob_get_clean(); } add_shortcode( 'custom_login', 'shortcode_custom_login' );
Here I am creating a shortcode custom_login
. This shortcode accepts the redirect parameter. Also, this function uses our custom_html_form()
to show HTML form to our user.
Using the shortcode on the frontend
We will create a simple page in our backend and name it Login. Now use the in-built Gutenberg shortcode block. Put this inside the block.
[custom_login redirect="http://yoursite.com/wp-admin"]
Do you see something different? I am talking about redirect. I am redirecting a user to the dashboard after he/she successfully logs in. Be sure to replace yoursite.com
with your website name.
Conclusion
I hope everything is clear now. It was all about how to create a custom login page in WordPress? If you doubt or face any issues, I am ready to help put your message in the comment box below.
Now, I want your support. Please do share this tutorial if it helped you, also. Don’t forget to subscribe to our YouTube channel and like our Facebook page.
Robert Gentile says
This was just what I was looking for!
I had to add some { } around your last media query and your .site-inner CSS caused some display issues on my site so I removed it. But other than those changes I was able to cut and paste your solution and it worked.
Thanks for making this available.
Raashid Din Dar says
Hello Robert,
Thanks for pointing out the issue. I somehow forgot to add those braces.
Anwar Kham says
Works like a Charm I was looking for such a Nice and Perfect Article.Highly Recommended Keep Posting.Thanks a Million
Raashid Din Dar says
Thank You @Anwar Kham for your kind words. Keep visiting
Brian Flynn says
I am getting the following error when I try to use the script in WordPress 4.9.8:
“Cannot modify header information – headers already sent by (output started at \Root\htdocs\class.wp-style.php)…
Any thoughts?
Raashid Din Dar says
Hello Brian,
I tested the code in 4.9.8 but i am not getting any error. It maybe problem with php opening and closing tags like you may be calling the tags inside the already opened tags. Please share the line number also, so i can figure it out.
Hope this helps. If there is anything, please don’t hesitate to share.
vimal says
Hi,
thanks for your nice tutorial.can we get sing in with fb,twitter,google plus social media option
Raashid Din Dar says
Hi,
Soon I will write a tutorial on that.
Thanks for your kind words.
Chinmay Rajyaguru says
I am thankful to websiteguider.com Mr.Raashid. Perfect login page!
On a few things need to get focused:
Instead of using directly @media only screen and (max-width: 768px)
.site-inner {
padding: 5% 5% 5%!important;
}
Use this:
@media only screen and (max-width: 768px){
.site-inner {
padding: 5% 5% 5%!important;
}
}
At this stage, the only thing left to do is to set redirections to ultimately eliminate the default login page of WordPress. Do so by placing these lines at the end of your functions.php file:
/* Main redirection of the default login page */
function redirect_login_page() {
$login_page = home_url(‘/login/’);
$page_viewed = basename($_SERVER[‘REQUEST_URI’]);
if($page_viewed == “wp-login.php” && $_SERVER[‘REQUEST_METHOD’] == ‘GET’) {
wp_redirect($login_page);
exit;
}
}
add_action(‘init’,’redirect_login_page’);
/* Where to go if a login failed */
function custom_login_failed() {
$login_page = home_url(‘/login/’);
wp_redirect($login_page . ‘?login=failed’);
exit;
}
add_action(‘wp_login_failed’, ‘custom_login_failed’);
/* Where to go if any of the fields were empty */
function verify_user_pass($user, $username, $password) {
$login_page = home_url(‘/login/’);
if($username == “” || $password == “”) {
wp_redirect($login_page . “?login=empty”);
exit;
}
}
add_filter(‘authenticate’, ‘verify_user_pass’, 1, 3);
/* What to do on logout */
function logout_redirect() {
$login_page = home_url(‘/login/’);
wp_redirect($login_page . “?login=false”);
exit;
}
add_action(‘wp_logout’,’logout_redirect’);
Raashid Din Dar says
Thanks for kind words.
I will look at these functions.
AxiBook says
Thanks for this code. This is wonderful. However, while implementing this, I found some issues.
1. The login page was not redirecting to admin dashboard
2. However, the admin login bar was visible. But, when trying to access the admin dashboard, it was again redirecting to wp-login.php page.
These two were the major issues and I have fixed those two and it works simply perfect now. Now it works like a cham and I enjoy this a lot.
Thanks for sharing this code.
Raashid Din Dar says
Thanks for kind words.
The answer to your issues.
1. As this is custom login page so we don’t know how the user will use it like if he wants to redirect the customer to main dashboard or any other file.
2. The code successfully logs you in to WordPress dashboard. But in code you change the behaviour.
Thanks again.
asdf says
How did you solved this? I am facing same issue
Matteo says
Hi, unfortunately I get 5 errors of the same type:
Warning: Cannot modify header information
When I log in correctly.
While if the mistake on purpose everything works correctly.
Why does this happen?
Thanks a lot.
Sincerely,
Feduzi Matteo.
Raashid Din Dar says
Hello,
Be sure you aren’t writing the PHP tag.
Also, I am rewriting this tutorial.
Thanks for stopping.
mostafa says
$username = $wpdb->escape($_REQUEST[‘username’]);
$password = $wpdb->escape($_REQUEST[‘password’]);
$remember = $wpdb->escape($_REQUEST[‘rememberme’]);
$wpdb->escape is deprecated since version 3.6’
how to solve it?
thanks for this tutorial
Raashid Din Dar says
Hi,
I am updating the tutorial with new code soon.
Thanks for letting me know
Prashant Kansal says
I am Facing one issue, The login page is redirecting to the Home page and when I trying to access the admin dashboard, it was again redirecting to wp-login.php page
Raashid Din Dar says
Hi,
Sorry for inconvenience.
I am rewriting this tutorial please consider checking the article again, once it is updated.
Thanks
Amar Verma says
Hi
Nice article.
How we can replace password with usermeta mobile
reg.
Amar Verma says
Hi
I have wordpress wbesite, I want something like mentioned below:
1st step: User login with UserName and Password (Traditional WP login form) – Its working well.
Issues and not able to do below steps:
2nd Step: User want to post or comments then a popup will come and ask DoB or mobile number etc(from usermeta table) to verify the user. If information is correct, he can post and if information is not correct show error message.
Is it possible? If so, please help me.
Reg.
Raashid Din Dar says
Hi,
It is a long process. It is not possible to write this long tutorial. You can hire a developer (best option).
Thanks
Kambro says
Thank you for your post.
I should like to keep the whole style of my website’s theme (footer, button style, etc).
I have yet create a page with Elementor with a login form.
How can I define this page as login page ?
Thank you by forehand.
Raashid Din Dar says
Hi,
Firstly, you can avoid adding the styles.
Secondly, I am not a big fan of page builder plugins, so don’t know how the elementor works.
I created the tutorial for general audience.
Otherwise if you need any help with code please don’t hesitate to ask.
Thanks.
Kambro says
Thank you for your answer.
Arshpreet kaur says
css code is not working could you help me
Raashid Din Dar says
Hi,
What is the problem you are facing.
PRO GaMING says
How to add login with Google to this custom login page.please tell.as I want to apply my styles to those button so plugins can’t be used
Musarrof says
I didn’t find any JS and CSS code here. Is it normal or I miss ? But form is working fine, Thanks for you time.
Aminul says
Thank you for this great article.
Do you have password recovery of this system?
Thanks
Aminul
Mark says
Hi man,
Could you please put all code in folder and make it downloadable please
Thanks
Mark
Raashid Din Dar says
Hi,
Thanks for leaving a valuable comment. I will update the tutorial ASAP to adress the request made.
francisco javier arenas says
thanks, Raashid for the tutorial, but I feel some parts are missing: for example, in the code, we are enqueuing some javascript scripts that are not in the tutorial… what do you think about creating a GitHub project or gist with all the code? I’ve followed the tutorial and I think a logout link could be useful too:
I’ve implemented that one after line 56 in login-functions.php
Savan Patel says
When I active plugin then show the error.
The plugin could not be activated because it triggered a fatal error.
Warning: require_once(/home/workdemo/public_html/walrus/wp-content/plugins/custom-plugin/shortcodeshttp://workdemo.me//walrus/wp-content/plugins/custom-plugin/login-shortcode.php): failed to open stream: No such file or directory in /home/workdemo/public_html/walrus/wp-content/plugins/custom-plugin/custom-login.php on line 26
Fatal error: require_once(): Failed opening required ‘/home/workdemo/public_html/walrus/wp-content/plugins/custom-plugin/shortcodeshttp://workdemo.me//walrus/wp-content/plugins/custom-plugin/login-shortcode.php’ (include_path=’.:/opt/cpanel/ea-php74/root/usr/share/pear’) in /home/workdemo/public_html/walrus/wp-content/plugins/custom-plugin/custom-login.php on line 26
Raashid Din Dar says
Hi,
Thank you for commenting.
Please give me five minutes, I will provide the solution.
Thanks
Raashid Din Dar says
Hi,
I tested the code and it is working. I have simplified the process by uploading the file to Google Drive.
You can download the file. Here is the link.
https://drive.google.com/file/d/1bq27AxV_Cj_unt9byu0dYh0nAUSycT7b/view?usp=sharing