Building a Search bar for your Gatsby site with Typesense
Tags: gatsby, showdev
Published: 2020-10-20 03:19:39

---
canonical_url: https://medium.com/@jasonbosco/building-a-search-bar-for-your-gatsbyjs-site-with-typesense-3e277dc33942
---

# 🤔 Context
Gatsby currently has [two options](https://www.gatsbyjs.com/docs/adding-search/) for adding a search bar to your site:

1. Using a Javascript-based search library like Lunr / ElasticLunr
2. Using a proprietary Search-as-A-Service like Algolia

# 😞 The Problem

While a JS-based search library works great for small sites with limited content, for large Gatsby sites, it ends up bloating your bundle size because the entire search index needs to be bundled with your site’s assets. This large bundle needs to be downloaded to your visitors’ browser which unfortunately increases your site’s page load times.

Algolia works great for documentation sites, since Algolia offers a free DocSearch service. However for Gatsby sites with a large amount of traffic or content or both, Algolia can become expensive quickly. It is also a proprietary solution and the [Gatsby plugin for Algolia](https://www.gatsbyjs.com/plugins/gatsby-plugin-algolia/) is currently in beta and not officially supported.

# ✨ The Solution

Enter [Typesense](https://github.com/typesense/typesense), an *open source search engine* that is simple to use, run and scale, with clean APIs and documentation. Think of it as an *open source alternative to Algolia* and an *easier-to-use, batteries-included alternative* to ElasticSearch.

Read more about Typesense’s out-of-the-box features [here](https://github.com/typesense/typesense#features).

The [Gatsby-Typesense](https://www.gatsbyjs.com/plugins/gatsby-plugin-typesense/) plugin helps you to index data from your Gatsby site to a Typesense Search cluster and then quickly build a powerful instant search interface using [InstantSearch.js](https://github.com/algolia/instantsearch.js).

The cool thing about this plugin is that it works for both static and dynamic Gatsby sites. It does not depend on you using Markdown, React or any particular plugin. It scans the output of your Gatsby public folder for HTML files and directly indexes content from the markup.

# How to add Search to a Gatsby site

The rest of this article will walk you through how you can add an Instant Search bar to your Gatsby site with Typesense.

I’m going to assume that you already have a working Gatsby site. If not, [here](https://www.gatsbyjs.com/tutorial/) is a good place to learn how to.

## 👣 Step 1: Install the Typesense plugin for Gatsby

From your Gatsby site’s root:

```bash
npm install gatsby-plugin-typesense @babel/runtime
```

## 👣 Step 2: Start a Typesense server

The simplest way to run a Typesense server is using Docker:

```bash
mkdir /tmp/typesense-server-data

docker run -i -p 8108:8108 -v/tmp/typesense-server-data/:/data typesense/typesense:0.15.0 --data-dir /data --api-key=xyz --listen-port 8108 --enable-cors
```

You can also download native binaries from the [downloads](https://typesense.org/downloads/) page.

If you’d prefer a hosted version of Typesense, you can also spin up a cluster on [Typesense Cloud](https://cloud.typesense.org/).

## 👣 Step 3: Configure the Plugin

In your `gatsby-config.js` file, configure the `gatsby-plugin-typesense` plugin:

```javascript
// gatsby-config.js

module.exports = {
  plugins: [
    {
      resolve: `gatsby-plugin-typesense`,
      options: {
        publicDir: `${__dirname}/public`, // Required
        collectionSchema: { // Required
          name: "pages_v1",
          fields: [
            {
              name: "title",
              type: "string",
            },
            {
              name: "description",
              type: "string",
            },
            {
              name: "tags",
              type: "string[]",
              optional: true,
              facet: true,
            },
            {
              name: "page_path", // Required
              type: "string",
            },
            {
              name: "page_priority_score", // Required
              type: "int32",
            },
          ],
          default_sorting_field: "page_priority_score", // Required
        },
        server: { // Required
          apiKey: "xyz",
          nodes: [
            {
              host: "localhost",
              port: "8108",
              protocol: "http",
            },
          ],
        },
      },
    },
  ],
}
```

To learn more about what the different configuration options mean, read [this section](https://github.com/typesense/gatsby-plugin-typesense/blob/master/README.md#heres-what-the-options-mean) of the plugin's documentation.

## 👣 Step 4: Markup your content

Add a data attribute called `data-typesense-field` to any HTML elements that contain the data you want to be indexed for that page.

For example, if you have the following HTML snippet in a file:

```html
<!-- ./public/about/index.html -->

...

<h1 data-typesense-field="title">About Us</h1>
<p data-typesense-field="description">
  Hello, we are Stark Industries.
</p>
<div>
  <span data-typesense-field="tags">about</span>
  <span data-typesense-field="tags">misc</span>
</div>

...
```

When you build your site, the plugin will index this page as the following structured document in Typesense:

```json
{
  "title": "About Us",
  "description": "Hello, we are Stark Industries.",
  "tags": ["about", "misc"],
  "page_path": "/about/",
  "page_priority_score": 10
}
```

You can also add any arbitrary fields to the document, by adding the `data-typesense-field` data attribute to any HTML element and adding the corresponding field to the schema under the plugin’s configuration options.

Now, you want to run `gatsby build` and the plugin will automatically be triggered post-build and it will index the content you’ve marked up into Typesense 🎉

## 👣 Step 5: Build your Search UI

The good folks over at Algolia have built and open-sourced [Instantsearch.js](https://github.com/algolia/instantsearch.js) which is a powerful collection of out-of-the-box UI components that you can use to compose interactive search experiences quickly.

Typesense has an integration with InstantSearch.js (and its [React cousin](https://github.com/algolia/react-instantsearch)), that lets you use a Typesense cluster with InstantSearch.js UI components:

[https://github.com/typesense/typesense-instantsearch-adapter](https://github.com/typesense/typesense-instantsearch-adapter)

First, install the react-instantsearch and the adapter:

```bash
npm install typesense-instantsearch-adapter react-instantsearch-dom @babel/runtime
```

Here’s a quick minimal example of a search interface using react-instantsearch:

```javascript
import { InstantSearch, SearchBox, Hits, Stats } from "react-instantsearch-dom"
import TypesenseInstantSearchAdapter from "typesense-instantsearch-adapter"
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter({
  server: {
    apiKey: "xyz", // Be sure to use the search-only-api-key
    nodes: [
      {
        host: "localhost",
        port: "8108",
        protocol: "http",
      },
    ],
  },
  // The following parameters are directly passed to Typesense's search API endpoint.
  //  So you can pass any parameters supported by the search endpoint below.
  //  queryBy is required.
  additionalSearchParameters: {
    queryBy: "title,description,tags",
  },
})
const searchClient = typesenseInstantsearchAdapter.searchClient
export default function SearchInterface() {
  const Hit = ({ hit }) => (
    <p>
      {hit.title} - {hit.description}
    </p>
  )
return (
      <InstantSearch searchClient={searchClient} indexName="pages_v1">
        <SearchBox />
        <Stats />
        <Hits hitComponent={Hit} />
      </InstantSearch>
  )
}
```

InstantSearch.js supports a variety of [additional search widgets](https://www.algolia.com/doc/guides/building-search-ui/widgets/showcase/react/). Read more about how to use them in their documentation [here](https://www.algolia.com/doc/guides/building-search-ui/getting-started/react/).

**🔥 And that’s it! 🚀**

You now have a working search bar, with Instant Search, typo tolerance and more, powered by Typesense and InstantSearch.js.

Please let me know if you run into any issues in the comments.