DEV Community

Cover image for Build a search application with React and Typesense
Salem Olorundare👨‍💻
Salem Olorundare👨‍💻

Posted on

Build a search application with React and Typesense

One common feature most applications have is the search feature. This feature allows the user to search through different collections of products or databases. Some applications take more time than they should, to search through the database for simple products or any other resource, to get the results to the user in due time.

E-commerce platforms like Amazon, eBay, and Flipkart make use of the search feature to enhance the user experience and get the right product. displayed to its customer.

Search-based applications are very common as they help to query the database faster with little or no technical experience through a search box.

What is Typesense?

Building a fully functional search feature from scratch takes a lot of time, energy, and resources to create. Managing the user input and search application against cyber attacks can be daunting.

Typesense is a free and open-source search engine for instant search-as-you-type experiences for application users. Typesense reduces the need for developers to build a search engine for each web application from scratch. This contributes vastly to a developer’s productivity when developing applications.

Sometimes, typo errors from the user can lead to errors in search results. Typesense has a typo detection feature that detects errors and makes sure the right and expected result is returned it the user. Typesense is also incredibly fast when it is being queried.

With Typesense, developers can easily add a search feature to their application with less and reduced effort.

Setting up a Typesense account

Let’s begin by setting up a Typesense account to connect with our React application

Step 1: Create an account

Typsense makes it easy to create an account with Github. Let’s head over to Typesense to create an account and get our API keys.

type1

Step 2: Create a new Cluster.

After creating an account, we would need to create a cluster to manage our different collections of data.

type2

Leave the defaults and click the launch button to create the cluster.

type3

Clicking on the launch button will get Typesense to start creating the cluster. This would take a couple of minutes to get the cluster created as it is shown in the image below.

type4

After the cluster has been created, we can then create our API key and get our host name. We would need this information to connect our app with Typesense.

Note: We would be using Typesense cloud to connect our app with Typesense, as it is an easier way to connect with Typesense.

Below is the host name and port number we will be using. Store this information somewhere you could easily have access to.

type5

Step 3: Get API keys

Click on the Generate API keys to get the API key for our app. This will download a .txt file where you will find all information to connect your app with Typesense. This includes the API keys, host name, and also port number.

Note: We will be making use of the Search only API key for this tutorial.

Now, we are all set to connect our app with Typesense. Yipee!!!

Connect Typesense to React application

We would be creating a simple search application with Typesense and React. Let’s have our React app created first.

Create a React app with the following commands and install these dependencies.

  1. Create a React app

    npx create-react-app book-search-app

  2. Install Typesense and react-instant-search

npm install typesense

`npm install react-instantsearch-dom`

`npm install typesense-instantsearch-adapter`
Enter fullscreen mode Exit fullscreen mode

These are the libraries we would use to build our search application. The react-instantsearch used in this tutorial is a react open-source UI library that lets you quickly build and integrate a search interface(UI) into your application. We would see how to use it in the tutorial.

Now that we have our React application setup, we can start to connect with Typesense.

To connect and make changes to our cluster we will need to set up a Typesense client. The Typesense client would allow us to run commands to create clusters, create collections and also build schema, which holds the structure of how data are to be stored in the collection.

Creating and building Typesense schemas in React

To create a Typesense client and build our book schema(book structure), create a file in your React root directory and give it a name of your choice, in my case I gave it a name with loadData.js. This file will hold all the configurations needed to connect and create our Typesense client.

Before we continue, let’s get our books.json file ready. This file is a collection of different book titles and their descriptions. This is the file we want to query and search through to get information faster. Click here to download the book.json file.

Now, let us create a self-executing function so that when our app begins to run, our function also runs. Copy and paste the code below into your app.

// loadData.js
const Typesense = require('typesense');

module.exports = (async () => {
    //Configure Typesense
  const TYPESENSE_CONFIG = {
    nodes: [
      {
        host: process.env.TYPESENSE_HOST, // For Typesense Cloud use xxx.a1.typesense.net
        port: '443', // For Typesense Cloud use 443
        protocol: 'https', // For Typesense Cloud use https
      },
    ],
    apiKey: process.env.TYPESENSE_APIKEY,
  };

//Create and instance of Typesense client
  const typesense = new Typesense.Client(TYPESENSE_CONFIG);

// Build Schema
  const schema = {
    name: 'books',
    "fields": [
      {
        "facet": false,
        "index": true,
        "name": "title",
        "optional": false,
        "type": "string"
      },
      {
        "facet": true,
        "index": true,
        "name": "authors",
        "optional": false,
        "type": "string[]"
      },
      {
        "facet": true,
        "index": true,
        "name": "publication_year",
        "optional": false,
        "type": "int32"
      },
      {
        "facet": false,
        "index": true,
        "name": "ratings_count",
        "optional": false,
        "type": "int32"
      },
      {
        "facet": false,
        "index": true,
        "name": "average_rating",
        "optional": false,
        "type": "float"
      }
    ],
  };

// Import book.json
  const books = require('./dataset/books.json');

//Checks if the collection exists
  try {
    await typesense.collections('books').retrieve();
    console.log('Found existing collection of books');
  } catch (err) {
    console.error(err);
  }

// Create Booke schema
  await typesense.collections().create(schema);
  console.log('Creating schema...');

//Upload book.json to Typesense Database
  try {
    const returnData = await typesense
      .collections('books')
      .documents()
      .import(books);
  } catch (err) {
    console.error(err);
  }
})();
Enter fullscreen mode Exit fullscreen mode

Let's break this down

  1. To make the Typesense library accessible and usable we imported the typesense library
  2. We then created a const to store our Typesense configuration. This configuration includes the setting up of the host, port, protocol, and apikey. All these parameters are in the file we downloaded from Typesense earlier when we created our cluster.
  3. Then we made a new instance of Typesense client, using the Typense we imported earlier in the code.
  4. To create the schema for our book collection we created a const and put in the structure of each field that each of the books in our data provides us with. Then we created this schema with the typesense.collections().create(schema) command.
  5. Finally, we uploaded our books.json file to the Typesense database so that this file can be indexed when we make searches.

To make this function self-executing, navigate to your package.json file and add "indexer": "node loadData.js" to the script option. Now, this function will run each time the application runs.

With the code above, we have successfully created and configured our Typesense client. Now we can move on to building a search UI to query this data and get different results from each search that we make.

That is all for the first part on how to set up and configure Typesense with your React application.

Now, let’s dive into the section, where we would start querying our Typesense and React application.

Building Search UI with React-instantsearch and Typesense

In this section, we would create a simple UI to display our search input and our results. Copy and paste this code into your App.js file.

import React from 'react';
import './style.css';
import {
  InstantSearch,
  SearchBox,
  Configure,
  Hits,
  Pagination,
} from 'react-instantsearch-dom';

import TypesenseInstantSearchAdapter from 'typesense-instantsearch-adapter';

const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter({
  server: {
    nodes: [
      {
        host: procsess.env.TYPESENSE_HOST,
        port: '443',
        protocol: 'https',
      },
    ],
    apiKey: process.env.APIKEY,
  },
  additionalSearchParameters: {
    query_by: 'title',
  },
});

export default function App() {
  const Hit = ({ hit }) => {
    return (
      <div className="hit">
        <div className="hit-image">
          <img alt={hit.authors} src={hit.image_url} />
        </div>
        <div className="hit-content">
          <div className="hit-price">{hit.title}</div>
        </div>
      </div>
    );
  };
  return (
    <div>
      <h1>Search Books</h1>
      <InstantSearch
        indexName="books"
        searchClient={typesenseInstantsearchAdapter.searchClient}
      >

        <SearchBox autoFocus />
        <Configure hitsPerPage={5} />
        <Hits hitComponent={Hit} />
        <Pagination />
      </InstantSearch>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Let’s explain the code above

  1. We made the necessary imports to set up Typesense and use instantsearch
  2. TypesenseInstantSearchAdapter configuration. The TypesenseInstantSearchAdapter helps us to to configure Typesense for any search query.

    We have configure the host, port, protocol and the apikey parameter.

    The additionalSearchParameters is used to configure search parameters. i.e where to search how to do a search when it is queried.

  3. The <InstantSearch /> component allows us to wrap all our react-instantsearch components to give us the UI display: the search box and the results. Add the search components to your app and configure it with the right parameters.

  4. To display and make a simple search bar we used the <SearchBox /> that we imported earlier. This should display for us a search bar to start making our queries.

  5. The <Hits /> components is used to to display the search results.

If you have made it to this point, congratulations, you have successfully created a search application with Typesense and React. Now, let’s test our application to see if everything works fine. Run your React app and see if you have the following displayed on your screen.

book search

As we can see, a list of book images and their titles are being displayed when we make a search through the search box that is provided to use by the react-instantsearch. These data (images and titles) are gotten from the books.json file that we uploaded to the Typesense database earlier.

Conclusion

With this, we have successfully integrated Typesense to our React application and built a search feature or search application.

Typesense is a very useful tool for developing application features within the best possible time. There are lots that we can do with Typesense as a search engine. This is a tutorial to get you familiar with Typesense and how to use it with your Javascript(React) application.

Check out the documentation here to learn more about Typesense.

Discussion (0)