27th December 2022 3 min read

How to setup Algolia search with Remix

Burak Tarım

In this article, we will build a simplified version of our client Heavybit's library browse module.

We built it using Algolia search with Remix.

You can check the full working version from here.

Also, please don't forget to read our case study with our client Heavybit.

To build a simplified version of the library browse page, we are going to follow these steps;

1. Create an empty Remix project

2. Create the library browse component

3. Create custom hits and search box

4. Add widgets to the library browse

5. Apply some styling

sh
1npx create-remix@latest

We will use algoliasearch and react-instantsearch-hooks-web packages to make algoliasearch work in our project.

You can read more about instant-search from Algolia docs.

We are going to install them with these commands;

sh
1npm i react-instantsearch-hooks-web algoliasearch

We are going to use tailwind CSS to style this project.

You can add tailwind CSS by following these steps in tailwind docs.

Create a React component and Import InstantSearch from "react-instantsearch-hooks-web", init the searchClient and the index name. We will use custom components in this InstantSearch component.

typescript
1// Import packages2
3import { InstantSearch } from "react-instantsearch-hooks-web";4import algoliasearch from "algoliasearch/lite";5
6// Inıt the search client7
8const searchClient = algoliasearch("APP_ID", "SEARCH_KEY");9
10export default function LibraryBrowse() {11  return (12    <div>13      <InstantSearch indexName="INDEX_NAME" searchClient={searchClient}>14        {/** Custom widgets */}15      </InstantSearch>16    </div>17  );18}19

Now we will create the hits and the search box widget with instant search hooks.

3.1 Custom hits component

In this component, we are going to use useHits() hook. You can read more about it from Algolia docs.

All we will do is loop through the hits array and create our custom list.

typescript
1import { useHits } from "react-instantsearch-hooks-web";2
3export default function CustomHits() {4  const { hits } = useHits();5
6  return (7    <ul>8      {hits.map((hit: any) => (9        <li className="list-none" key={hit.objectID}>10          <img src={hit.image} />11          {hit.title}12          {hit.content?.substr(0, 100)}13        </li>14      ))}15    </ul>16  );17}18

3.2 Create custom search box

In this component, we are going to use useSearchBox() hook. Here are the docs about it.

We will use the refine and the clear functions of this hook. We need to call refine when the user types something and clear when the user wants to delete the query.

typescript
1import React from "react";2import { useSearchBox } from "react-instantsearch-hooks-web";3
4export default function CustomSearchBox() {5  const { refine, clear } = useSearchBox();6  const [val, setVal] = React.useState("");7
8  React.useEffect(() => {9    refine(val);10  }, [val]);11
12  return (13    <div>14      <input15        type={"text"}16        value={val}17        onChange={(e) => {18          setVal(e.target.value);19        }}20      />21      <button22        onClick={() => {23          clear();24          setVal("");25        }}26      >27        X28      </button>29    </div>30  );31}32

Now we can import our custom widgets and add them to InstantSearch with pagination.

typescript
1// Import packages2
3import { InstantSearch, Pagination } from "react-instantsearch-hooks-web";4import algoliasearch from "algoliasearch/lite";5import CustomSearchBox from "./CustomSearchBox";6import CustomHits from "./CustomHits";7
8// Inıt the search client9
10const searchClient = algoliasearch("APP_ID", "SEARCH_KEY");11
12export default function LibraryBrowse() {13  return (14    <div>15      <InstantSearch indexName="INDEX_NAME" searchClient={searchClient}>16        {/** widgets */}17        <CustomSearchBox />18        <CustomHits />19        <Pagination />20        {/** widgets */}21      </InstantSearch>22    </div>23  );24}25

Now we can clear everything under the ./app/routes/index.tsx file and import our LibraryBrowse component.

typescript
1import LibraryBrowse from "~/components/LibraryBrowse";2
3export default function Index() {4  return (5    <div>6      <LibraryBrowse></LibraryBrowse>7    </div>8  );9}10

If you go to http://localhost:3000, you can see a fully functional library browse component, and search and pagination work well.