I Doubled my Income in a Year

WordPress allowed me to get a better job & better projects in just a Year. I will give you tips, tricks and guide you into WordPress development so you can get more income. Sign up to my 7-day email course!

How to create a WordPress Login Form with React

Custom solution and membership site built on WordPress require some custom WordPress login solutions. In this tutorial we will create a WordPress Login Plugin that will use React for processing login. With the help of React, we can have more than 1 widget and each of them will change its appearance when our user logs in.

The code in this tutorial can be easily used on any of your WordPress solutions. Remember to edit the code and configure it to your needs.

Download the code react-login.

WordPress Login Form

As we always do with a plugin, we first must create a simple file with some information about our plugin.

Create a folder react-login in the plugins folder and also create a file inside that folder react-login.php.

That is some simple information just so that we can see it in our Plugins menu. Go to the admin area and activate it.


In the last tutorial where we learned how to create a WordPress Widget with ReactJS and WP REST API, we have also included the React scripts. We will do the same here.

Create two files and name them react.min.js and react-dom.min.js. In the first one add this:

In the second one add this:


We will use a widget for our WordPress Login form so that we can easily add as many widgets as we want and test the code to see how it handles one or many login forms. Add this code to our plugin file.

We have defined our Widget ID to be react_login_widget. We will use this ID to check if our Widget is active so that we can enqueue scripts. The method form will create an input element in the WordPress admin area. The next method, update will save the title we add in the WordPress admin area. The last method widget is the code that will be processed on the front.

In this method we are creating a simple div element with the class="react_login". We are not using ID because we could have more than 1 widget here. Instead, we are using the class react_login because the class can be used more than once on a web page. Since we will target this class, we can place the class on many places on our web page and we will have the login form or user information. It does not have to be a widget, it could even be a simple shortcode.

I leave that up to you to decide how you will implement this into your solution 🙂

Enqueuing Scripts

Before enqueueing our scripts, we will check if our WordPress Login form widget is active. If it is, then we will enqueue the scripts for React, ReactDOM and we will also enqueue the babel script that will handle the JSX transformation of our JavaScript. This is used only for the purpose of this tutorial.

I would recommend to use babel only in development and transform your JSX using Gulp or similar before pushing it to production. In the last tutorial about React, which I have listed above, I have written React elements using vanilla JavaScript. Now, I will use the JSX so that you can see how to do it with JSX also.

Let’s enqueue them now by adding this to our WordPress Login plugin:

We are also localizing our babel-js script before enqueueing it. You could actually use some localized strings for your JavaScript, but we will use it here to add the url to our AJAX in WordPress and to create a nonce that we can use for security reasons.

By using wpReactLogin.ajax_url in our JavaScript, we will have the complete URL to the AJAX inside WordPress.

Coding with React in JSX

You are here mostly for this, right? 🙂 We will now code using React and JSX for our WordPress Login form. Let’s start by adding the script. We will add our script directly in the footer and that is only for the purpose of this tutorial. You should babelify your script and enqueue it as we did the other React scripts.

We will have to use the babel indicator in our script element, so let’s start by adding this:

Since we are using text/babel, our babel script will read the code inside that and transform any JSX into vanilla JavaScript right inside the browser.

The React Root

Since our WordPress Login form will be able to handle more than 1 widget built with React, we have to get every single class="react_login" element and instantiate the React Object on it using ReactDOM. Add this to our script:

We are first getting all the elements with that class. The variable reactLoginDoms is an array and it will be used to store every ReactDOM we have instantiated. By using the for loop we are iterating through every element we have found and we are instantiating a ReactDOM on it. Once instantiated, we are pushing it to our store reactLoginDoms.

We are also adding a property order to our React Root, so that we know which form has been processed. Our React Root element is ReactLogin, so let’s add the code for it:

This looks like a lot, but bare with me. You will understand it pretty well. First, since this is our React root element that will pass the other values such as errors to other elements, we will store the state in it. We are setting an initial state in the method setInitialState.

Checking the Fields

The second method checkFields is our custom method for checking fields. This method will be called before processing the form. First, we are getting the order number so that we know which form is processed. The variables $username and $password are self-explanatory and they are defined as empty. We have done that because we do not know yet how to get the values.

The next step is to find out if there are more than 1 form. If there are, we are getting the value by using the order value. If there is only 1 form, we are then getting the value directly. The name reactLoginForm will be placed as the attribute name on our forms and that is why we can get the values using that code.

The same will be done with the username and the password inputs.

After that, we are setting an empty array of errors. If any input is empty, we are adding an error saying that the input is empty. After that, we are setting the state with the errors.

Handling the Form

The method handleForm will be called when the form is submitted. We will prevent the default processing and use our own. This is done by using the e.preventDefault(). After that, we are checking the fields for errors. If there aren’t any errors, we are processing an AJAX request.

We are setting the data that is passed in our AJAX request. The action part will be important when process the AJAX on the backend because we will use it for hooking in our function. To learn more about using AJAX in WordPress read AJAX in Plugins.

To get the values for our username and password, we are using the same approach as when we checked for errors. After all data is set, we are creating an AJAX request with the POST method.

If the received data has a parameter success and it is false, then it means we got an error. We are then getting that error message and save it to our state. This will trigger the ReactDOM to re-render and show our error.

If the success is true, then we will update all our ReactDOMs with that information. With the for loop we are iterating through each of our ReactDOMs that is stored in the reactLoginDoms. While iterating, we are setting the state to each of those ReactDOMs. In that state, we are setting the logged to be true and we are also setting the user data that we have received from WP_User object. The user data in that object is stored inside the data variable.

For any error that was given by the network or bugs within the code, we are using the alert but you can create your own error handling solution.

When the Component Mounted

When the React component did mount and it is ready to use, there is a method for initial settings. That method is componentDidMount

In this method, we are creating another AJAX request to our WordPress site and we are receiving the data if the user is already logged in or not. If it is we are again using the same approach as we did when handling the form. We will set the state with the same parameters.

Rendering the Root element

The last method is render and this method is deciding if we are going to see a login form or some user information. First, we are setting a $renderElement using the JSX for handling React Form element. On that element, we are passing some properties:

  • error – the array of errors
  • handleForm – the method for handling forms

We are creating a reverse flow by passing our method for handling forms. This is called reverse because we will add that method on our form attribute onSubmit. Our form will be rendered by another React Object ReactLoginForm. Once our form is submitted, we will call the method from our parent React root element ReactLogin.

If the user is logged in, then we will not render the ReactLoginForm, but instead we will render the ReactUserData. We are passing the user object there, so that we can use any data given by WP_User.

React Login Form

Our React root element is done. We now know that when our user is not logged in, he will see a login form. We will create that by rendering the React ReactLoginForm element. Let’s add that to our code:

We only have the render method defined here. We are creating the form with the attributes:

  • name: reactLoginForm – remember that we use that when retrieving values
  • onSubmit: {this.props.handleForm} – using {} to point out that this is not a string, but an object value. This value will be the method from our React root element

Before rendering the form, we are checking for errors. If there are any errors passed to our ReactLoginForm, we will render them using JSX in a ul element. We are also using dangerouslySetInnerHTML so that React won’t render the HTML as a string, but as good raw HTML. This will ensure that any links or other HTML elements provided in error messages gets properly rendered.

Don’t use that if you don’t trust the source of the HTML

We are then rendering the $errors above all the form fields.

React User Data

In the ReactUserData we will show only some simple data for the user. We will say hello to it and display his/her display name.

You can do a lot more to it because you have all the user data that is passed from our AJAX response. The data that is passed from WP_User can be found here.

Handling AJAX Requests

So far we have done very much. We have coded all our React objects and we only require the response form our AJAX requests. For you to better understand, I have divided them into two requests:

  • react_check_if_logged – Used on componentDidMount
  • react_login_user – Used on handleForm

Checking if the User is Logged in

The first action react_check_if_logged is passed in our AJAX request when our component mounts. This is only checking if our user is already logged in.

We are here using both AJAX action hooks wp_ajax_ and wp_ajax_nopriv. The nopriv0 then we are simply sending a JSON reponse with the success=0.

If the ID is something other than 0, we are sending a JSON response with the success being 1 and also the WP_User object.

Logging in the user

The second action react_login_user is passed in out AJAX request when the WordPress login form is submitted.

Since, we are posting data and interacting with our site, for security reasons, we are checking the nonce. If the nonce is correct, we are getting the username and password from the posted data. After we receive the data, we are calling wp_authenticate.

If the authentication did not pass because the username or the password is wrong, we will get a WP_Error object. If that is the case, we are then sending a JSON response with the success being 0. We are also passing a message retrieved from WP_Error.

If the authentication passed, we are sending a JSON response with the success being 1 and the user object retrieved from WP_User. Before sending that JSON, we are also setting the authentication cookie so that the logged in information is still there even after refreshing the page.


In this tutorial we have created a good WordPress Login form. We created a widget that can be placed around our WordPress website and share the same information if the user is logged in. Using React we have created a seemingly complex widget using some simple JavaScript (JSX).

Since our ReactDOM only targets the class react_login, we don’t even need a Widget for it.

If you have any question or suggestion, please do post them in the comments below.

About the Author Igor Benic

Web Developer who mainly uses WordPress for projects. Working on various project through Codeable & Toptal. Author of several ebooks at https://leanpub.com/u/igorbenic.

follow me on:

EDD for Developers

In less than 2 weeks, I have earned $1,800 by working on a custom solution with Easy Digital Downloads without any prior experience. Let me teach you how you can too with various custom solutions.

Get the eBook

Leave a Comment:

How to create a WordPress Login Form with React

by Igor Benic time to read: 10 min
Complete course to Become a WordPress DeveloperJoin the Course