How to quickly build a great React search experience Author Jason Stoltzfus

Building a search experience is a daunting task. At first glance, it looks simple: build a search bar, put data into a database, and then let the user enter content to query the database. However, there are many things to consider in terms of data modeling, underlying logic, and of course overall design and user experience.

We’ll show you how to build a great Reaction-based Search experience using Elastic’s open source Search UI library. The whole process takes about 30 minutes, and when it’s done, you can bring the search experience to any application that needs it.

But first, what makes building a search so challenging?

The search is daunting

A couple of weeks ago there was a great article going around calling Falsehoods Programmers Believe About Search. This article lists a number of false assumptions that developers consider when developing searches.

Here are some of the lies that many people believe:

  • “Customers who know what to search for will do it the way you expect them to.”
  • “You can write a query parser that consistently parses queries successfully.”
  • “Once this is set up, the search can be done the same way the next week.”
  • “Synonyms are easy to use.”
  • … There are many other highlights worth knowing, you should look for a read!

It’s important to note that search has many challenges, and they’re not just behind the scenes. You need to think about how to manage state, build components for filtering, faceting, sorting, paging, synonyms, language processing, and much more. But, to sum up:

Building a good search goes through two complex parts :(1) a search engine, which provides an API to support search; (2) Search library, which enriches search experience.

In terms of search engines, we’re going to introduce you to Elastic App Search.

For the Search experience, we’ll look at the OS Search library: Search UI.

When we’re done, a page like the one shown below will be generated

Search engine: Elastic App Search

Elastic App Search is available as a paid hosting service or as a free self-managed distribution. In this tutorial, we’ll be using a hosted service, but keep in mind that your team can use Search UI and Application Search for free with a basic license if you host it yourself.

The plan: Index documents representing the best video games of all time into search engines, and then design and optimize the search experience to search for them.

First, sign up to get a 14-day trial period – no credit card required.

Create an engine. You can choose from 13 different languages.

We called it video-games and set the language to English.

Download the Best Video Games Data Set, then upload it to App Search using an importer.

Next, click “Engine” and select the Credentials TAB.

Create a new public search key with limited engine access to access only the video-games engine.

Retrieve this new public search key and your host identifier.

It doesn’t look like much, but we now have a fully functional search engine that can search our video game data using optimized search APIs.

Here’s what we’ve done so far:

  • Create a search engine
  • Collected documents
  • A default schema is created
  • Retrieves a scoped, one-time credential that can be exposed to the browser

So here’s what we’ve done so far for application search.

Let’s start building the Search experience using the Search UI.

Search library: Search UI

We will usecreate-react-appTo create React applications with the scaffold utility:

Based on this, we will install the Search UI and apply the Search connector:

Start the application in development mode:

Open SRC/app.js with your favorite text editor.

We’ll start with some sample code and unpack it.

Note the remarks!

Step 1: Import the statement

We need to import the Search UI dependency and React.

The core components, connectors, and view components are contained in three different packages:

  • @elastic/search-ui-app-search-connector
  • @elastic/react-search-ui
  • @elastic/react-search-ui-views

As the course progresses, we will learn more about each package.

In addition, we will import the default stylesheet for this project so that we can get a good look and feel without having to write our own CSS lines:

Step 2: Connector

We obtained the public search key and host identifier from the application search.

Now is the time to use them!

The connector object in the Search UI uses credentials to hook up with and support application Search:

The Search UI works with any Search API. But with connectors, the search API does not require any deeper configuration to work.

Step 3: Configuration Options

Before we dive into configurationOptions, let’s take a moment to think about it.

We imported a set of data into the search engine. But what kind of data is that?

The more we know about data, the better we can understand how to present it to searchers and how to configure the search experience.

Let’s look at an object that is the best object in the dataset:

We see that it has several text fields like name, year, platform, and so on and some number fields like critic_score, global_sales, and user_score.

If we ask three key questions, we’ll know enough to build a solid search experience:

  • How will most people search? By the name of the video game.
  • What will most people want to see in a result? The name of the video game, its genre, publisher, scores, and its platform.
  • How will most people filter, sort, and facet? By score, genre, publisher, and platform.

We then can translate those answers into our configurationOptions:

Now that we have the Search UI connected to the Search engine, we choose how to manage the Search data, display the results, and browse the results. However, we need something to tie everything to the dynamic front-end components of Search UI.

Step 4: SearchProvider

This is the object that controls everything. The SearchProvider is where all the other components are nested.

The Search UI provides a Layout component that is used to draw a typical Search Layout. There are some further customization options, but we won’t go into them in this tutorial.

We’re going to do two things:

  1. willconfigurationOptionsThe incomingSearchProvider.
  2. Put some structure building blocks inLayoutAnd add two basic components:SearchBoxResults.

At present, we have completed the basic setup work in the front end. The back end has some extra details to work out before we can run it. We should also look at the relevancy model to fine-tune the search based on the unique needs of this project.

Quit app search…

Back in the lab

Application Search has powerful and optimized search engine features that can make once complex adjustments even more interesting. Fine relevancy adjustments and seamless architectural changes can be made with a few clicks.

We’ll start by tweaking the architecture to see it in action.

Log in to the application search engine, and then click Schema under the Manage section.

The schema is displayed. Each of the 11 fields is text by default.

In the ConfigurationOptions object, we defined two range facets to help search by number: user_score and critic_score. In order for the scope facets to work as expected, the field types need to be set to numbers.

Click the drop-down menu next to each field and change it tonumber(Numbers), and clickUpdate Types(Update type) :

The engine immediately re-indexed. Later, when we add faceted components to the layout, the scope filter will work as we expect. Now, let’s look at the real functional features.

This section is very important

There are three key relevance functions: synonyms, management, and relevance adjustment.

Select each function under the Search Settings section in the sidebar:

A synonym for

Some people drive cars, some people drive cars, some people might drive old cars. The Internet is global and people around the world use different words to describe things. Synonyms help you create a set of terms that are considered the same.

In the case of video game search engines, we know that people want to find Final Fantasy. But they might just type FF.

Click on theSynonyms(synonym), selectCreate a Synonym Set(Create a synonym set), and then enter these terms:

Click Save. You can add as many synsets as you want.

Now, a search for FF will have the same weight as a search for Final Fantasy.


Management is the most popular feature. What happens if someone searches for Final Fantasy or FF? There are a lot of games in the series, which ones will they get?

By default, the top five results will look like this:

1.Final Fantasy VIII

2.Final Fantasy X

3.Final Fantasy Tactics

4.Final Fantasy IX

5.Final Fantasy XIII

That seems wrong. Final Fantasy VII is the best game in Final Fantasy, and Final Fantasy XIII is not a very good game! 😜

Can we let people who search for Final Fantasy see Final Fantasy VII at the top of their list? Is it possible to remove Final Fantasy XIII from the results?

We can do it!

Click Curations (Administration) and enter the query: Final Fantasy.

Next, drag the Final Fantasy VII document up to Promoted Documents section by holding down the left-most handle of the table. Then, click the Hide Result button on the Final Fantasy XIII document — the eye icon with the penetration line:

Now, a search for Final Fantasy or FF will bring up Final Fantasy VII at the top,

And you won’t see Final Fantasy XIII at all. Ha ha!

We can promote and hide multiple documents. We can even sort the promoted documents to give us complete control over what is displayed at the top of each query.

Correlation adjustment

Click Relevance Tuning in the sidebar.

We search for a text field: the name field. But what if we have multiple text fields to search for (for example, the Name field and the Description field)? The video game data set we are using does not contain the Description field, so we will forge some documentation to carefully consider this field.

Assume the document looks something like this:

If someone wants to find the game Magical Quest, they type it as a query. However, the first result will be Dangerous Quest:

Why is that? That’s because the word “Magical” appears three times in the Dangerous Quest description, and search engines don’t know that one field is more important than another. Instead, it ranks Dangerous Quest even higher. That’s why correlation adjustments are made.

We can select a field from other content and increase its relevancy weight:

We can see that the correct item Magical Quest rises to the top as the Name field becomes more important after the weight is increased. All we need to do is drag the slider to a higher value and click Save.

Now, we use the application search to do the following:

  • Adjust the architecture, willuser_scorecritic_scoreChange tonumberField.
  • Fine tuning of the correlation model.

This concludes our introduction to these clever and advanced “dashboard” functions-each feature has a matching API endpoint, and if you don’t like the GUI, you can use the API endpoint to run each feature programmatically.

Now, let’s finish the introduction to Search UI.

Finishing touches

Your UI should now be up and running. Try a few queries and see what the results are. First, we lack some tools to explore our results, such as filtering, faceting, sorting, and so on, but we can search. We need to flesh out the UI.

In the initialsrc/App.jsIn the file, we import three basic components:

Based on what we defined for the configuration options, let’s add a few more components.

Importing the following components will enable functionality that is missing in the UI:

  • PagingInfo: Displays information on the current page.
  • ResultsPerPage: Configure the number of results to display on each page.
  • Paging: Navigate to different pages.
  • Facet: Filters and navigates data in a data-type-specific way.
  • Sorting: Rescheduled the results of the given field.

Once imported, components can be dropped into Layout.

The Layout component divides the page into sections into which each component can be placed by attributes.

It contains the following sections:

  • Header: Search box/search bar
  • bodyContent: Result Container
  • sideContent: sidebar, which contains faceting and sorting options
  • bodyHeader: Contains context-rich information around results, such as the current page and the number of results on each page
  • bodyFooter: Paging options for quick navigation between pages

Components render data. The data is retrieved according to the search Settings we provided in ConfigurationOptions. Now, we’ll place each component into the appropriate Layout section.

For example, we describe five faceted dimensions in ConfigurationOptions, so we will create five Facet components. Each Facet component will use a “field” property as the key to return data.

We put them, along with the Sorting component, into the SideContent section, and then put the Paging, PagingInfo, and ResultsPerPage components into the sections that best fit them:

Now, let’s look at the search experience in a local development environment.

Much better! We have a lot of options to browse search results.

We added a few extra features, such as multiple sorting options, and made publishers faceted filter by adding a single flag. Try searching with an empty query to browse all the options.

Finally, let’s look at one last feature of the search experience. It’s just popular

“Autocomplete” feature.

Done automatically

Searchers like autocomplete because it provides immediate feedback. Its recommendations come in two forms: results and queries. Depending on the approach, searchers will receive related results or potential queries that generate the results.

We will focus on the form of autocomplete query suggestions.

This requires two quick changes.

First, we need to add auto-completion to the ConfigurationOptions object:

Second, you need to do the auto-complete thingSearchBoxEnable a function of:

Well, it’s that simple.

Try a search. As you type, the autocomplete query recommendation is displayed.


Now, we have a good looking, fully functional search experience, and we avoid a lot of the pitfalls that people fall into when they try to implement search. Not bad for 30 minutes, isn’t it?

Search UI is a flexible modern React framework that can be used to quickly develop Search experiences. Elastic App Search is a powerful search engine built into ElasticSearch. This is a paid hosting service, or you can run it for free with an adequate basic license.

To learn more about Elastic technology, please follow and sign up for the webinar. The upcoming schedule is as follows:

Wednesday, February 19, 2020 15:00-16:00 Building Omni-Observable Instances Using Elastic Stack

Wednesday, February 26, 2016 15:00-16:00 Kibana Lens Webinar

Wednesday, March 4, 2020 15:00-16:00 Elastic Endpoint Security Overview Network

Monitor website resources with Elastic Stack Wednesday, March 11, 2020 15:00-16:00