The WordPress Search Widget is a classic HTML Form, but what if we want to show the results right away? In this tutorial, we will power up the WordPress Search Form with React and REST API to show the results immediately.

In a previous tutorial, I’ve shown how to use React for loading posts from various blogs through REST API. If you’re interested in such tutorial, you can check it out: How to use React to Render WordPress Content from the REST API. In that tutorial, I am also explaining how to install packages and prepare the package.json.

See it in action on the video on Twitter:

Setting up our Plugin

In terms of PHP, this will be a simple plugin. In terms of JavaScript, you’ll have to install several packages and create components so that our main JavaScript file can compile correctly. Since I’ve done that before, I will show you how to do it.

First, create a folder for your plugin. I will name it wp-search-react and then create a file inside with the same name wp-search-react.php. Inside that folder, create another one assets and inside that create another one js.

Inside the js folder, create a JavaScript file public.js and a folder components. The folder components will contain JavaScript files for each component in our code.

Installing Packages

To install packages that will compile our JavaScript, you need to have npm and node installed. If you don’t have that installed, go to https://nodejs.org and follow the instructions. Also, if you have older versions, update them.

Create a file package.json in the main folder of our plugin and put this inside:

This will list all the packages that are needed to follow this tutorial. Now you need to open your terminal (command prompt) and open our plugin folder in it (probably by typing several cd command to move into directories).

Once you’re in the main plugin folder wp-search-react (in terminal), type npm install. This might take some time to install all the packages.

Configuring Webpack

We will use Webpack to compile all the scripts together and also to transform ES6 or newer code into ES5 compatible code. If you’ve never configured Webpack, I would recommend reading/watching my tutorial: Configuring Webpack in WordPress for the First Time.

Create another file in our main plugin folder and name it webpack.config.js and put this in:

Now you can run npm run watch and Webpack should compile the public.js into public.min.js. On each change in that file, Webpack will recompile it.

Enqueueing our JavaScript

Before we go into JavaScript, we need to enqueue it on our site. Open our main plugin file and put all this information:

We are enqueuing our minified JavaScript file and we are also creating a global JavaScript object wp_react_js that will hold the REST URL for searching posts. The %s in the URL will be later replaced with the search term.

Activate the plugin from the Plugins page. 

Replacing the WordPress Search

The first code that we will write will replace the inner parts of the search form with our new React parts. We need to find all the search forms on the page and render React parts in each.

We are importing React and ReactDOM so we can use React and manipulate the DOM through ReactDOM. Now, we are finding all the Search forms and we will render our React Elements inside.

Rendering the React Search Form

We will create a new React Component that will hold our new Search Form. First, let’s change our main JavaScript file.

We are importing our new SearchForm Component (that we will create below) so we can use it within public.js. After importing it, we are putting that as a React Element using JSX in const searchFormElement. We are using that constant when rendering it for each search form on the page.

Search Form Component

The code above will not work without the SearchForm Component. Open the folder components and create a file searchForm.js.

Inside the render method we are creating a simple <input />. This input has an event registered onKeyUp. Once that is triggered, we are calling the method getResults(). To be able to use this inside that method, we are binding it in the constructor method.

Inside that constructor method we are also building starting the initial setup through super(props) and also preparing properties to be available through this.props. Since searchForm is our main Component (root), we will put the state there. In this state, we are setting 3 properties:

  • results – an array of retrieved posts from our search
  • loading – a boolean showing if the results are still loading
  • searched – a boolean showing if we have search terms in the input

Inside the method getResults(e) , we are receiving the event object to retrieve the value. But before doing anything, we are checking if are still loading the previous results. If that is true, we are not proceeding with the new search.

Fetching the Results

Let’s populate our method getResults(e) with the code that will fetch the results.

We are getting the search term inside the const search. If we have more than 2 letters in it, we will start searching. Before we start fetching the results, we are setting the state properties loading and searched to TRUE.

Then, we are getting the REST URL and replacing the %s with our search term. After that, we are fetching the results, transforming the results into JSON and finally set the results in our state. We are also putting the property loading to FALSE.

If the search term has less than 3 letters, we are setting properties loading and searched to FALSE.

Rendering the Results

We will not use this component to render the results directly. We will create another React Component for that.

At the beginning of the file, we are importing a new component searchResults. We are also adding that element to the render method and setting properties searchedloading and results. This properties will be available inside the searchResults component through this.props.

Search Results Component

Inside the folder components, add a new JavaScript file searchResults.js.

At the beginning of this file, we are again importing a new component that we will create next. Inside the searchResults component, we are preparing the properties through super(props). We don’t require anything else than a render method to show the results.

The variable let results will hold the text that will show under our field. If the results are still loading, we will show a text “Loading”. If there are any results, we will create a list of all retrieved posts. Each post will be rendered through the component searchResult.

If we are not loading the results but there are no results for the inserted search term, the text will be “Nothing Found”.

Search Result Component

This is the last component that we have to create. This one will be used only to render one single result. Create a new file in the folder components and name it searchResult.js.

In the render method we are returning a simple list element and we are rendering the content from the this.props.result object which we have passed in the searchResults component.

The Complete Plugin

I have prepared a complete plugin which you can use and then learn from reading the code. It is without any packages, so you would need to install them with npm install. To make it even more complete, play around with CSS to style the results better than the default styles.

This part is available only to the members. If you want to become a member and support my work go to this link and subscribe: Become a Member

Conclusion

With React, we can enhance the user experience of our visitors on our WordPress site. With simple tweaks such as this one, we can slowly improve the performance of our site. By using the REST API, we are also getting a boost in performance when searching our site because we don’t have to load the whole WordPress site again.

Have you tried using REST API for searching posts or other content? Have you tried using React in WordPress? Share your experience in the comments below!

If you’ve played around with it and written CSS for much prettier output, share that also!

Posted by 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.

4 Comments

  1. Work fine, thank you for this example.

    Currently for display below the searchfield the whole postobjects are returned from 10 first results. Would suggest to only get required fields and more possible results:

    ../posts?search=SEARCHTERM&_fields[]=link&_fields[]=title.rendered&per_page=100

    If you search for e.g. “core” it shows all real results for “core” and also all Gutenberg posts because text “wp:core” is in all of them, weird.

    Reply

    1. Yes, currently, it is only displaying number of posts set in posts_per_page setting. Thank you for the example, other readers will certainly appreciate that!

      As for the Gutenberg search issue, you might want to create a ticket for that in wp.org. That should not happen in my opinion.

      Reply

  2. Hey Igor, this is great and I’ve got it working like a charm. Maybe one suggestion: set a production build in package.json. I think I did this by doing the following (however, I really know nothing about webpack so this may not be the best method):
    //…
    “build:prod”: “webpack -p”,
    //…

    Reply

    1. Hi Alex, thanks for the suggestion. You’re correct and that might be a good thing to do for production builds. But as far as I know, this command will set Webpack in a production environment and then compile everything for production. But if you don’t have a configuration for production, that won’t do much difference.

      Maybe I am wrong here:) Not sure, but this could help: https://webpack.js.org/guides/production/

      Reply

Leave a reply

Your email address will not be published. Required fields are marked *