How to use react router with Algolia search hits?

Viewed 336

I'm using Algolia's react instant search and I want to know what code I can use that'll send me to a specific page when I click on a "hit" from the hits widget. I'm using Next.js.

Code:

import React from 'react';
import { useRef, useState, useEffect } from 'react';
import algoliasearch from 'algoliasearch/lite';
import { InstantSearch } from 'react-instantsearch-dom';
import { Index } from 'react-instantsearch-dom';
import { Configure } from 'react-instantsearch-dom';
import { Pagination } from 'react-instantsearch-dom';

const searchClient = algoliasearch(
  'XXXXXXXXXX',
  'XXXXXXXXXXXXXXXXXXXXXXXXXXX'
);

const Hit = ({ hit }) => <p>{hit.title}</p>;

import { connectSearchBox } from 'react-instantsearch-dom';

const SearchBox = ({ currentRefinement, isSearchStalled, refine }) => (  
  <form noValidate action="" role="search">
   <div className="container flex justify-center items-center px-4 sm:px-6 lg:px-8 relative">
    <input
      type="search"
      placeholder='Search Documentation'
      value={currentRefinement}
      onChange={event => refine(event.currentTarget.value)}
      className="h-7 w-96 pr-8 pl-5 rounded z-0 hover:text-gray-500 outline-none border-b-2"   
    />
    <i className="fa fa-search text-gray-400 z-20 hover:text-gray-500"></i>
    </div>
    <button onClick={() => refine('')}>Reset query</button>
    {isSearchStalled ? 'My search is stalled' : ''}
  </form>
);

const CustomSearchBox = connectSearchBox(SearchBox);

import { connectHits } from 'react-instantsearch-dom';

const Hits = ({ hits }) => (
  <table className="table-auto">
    {hits.map(hit => (
     <tbody>
     
     <tr>
     <td className="text-black font-bold" key={hit.objectID}>{hit.title}</td>
     </tr>
     
     </tbody>
    ))}
  </table>
);

const CustomHits = connectHits(Hits);

import { QueryRuleCustomData } from 'react-instantsearch-dom';

function SearchApp({location, history}) {
  const [showHits, setShowHits] = useState(false);

  return (
    <div>
      <>
        <InstantSearch
          indexName="prod_Directory"
          searchClient={searchClient}
        >
          <Index indexName="prod_Directory">
            {/* Widgets */}
            <div>
              <CustomSearchBox onFocus={()=>setShowHits(true)} onBlur={()=>setShowHits(false)}/>
              <CustomHits className="table-auto"/>
{/*
              {showHits ? <CustomHits className="table-auto"/> : null}
*/}
            </div>
          </Index>
          <Configure hitsPerPage={2} />
          <QueryRuleCustomData
            transformItems={items => {
              const match = items.find(data => Boolean(data.redirect));
              if (match && match.redirect) {
                window.location.href = match.redirect;
              }
              return [];
            }}
          >
            {() => null}
          </QueryRuleCustomData>
        </InstantSearch>
      </>
    </div>
  )
}

export default SearchApp

I couldn't find anything about this in the Algolia docs. Again, I want to be able to click on one of my hits, and have it redirect or route me to a specific page.

2 Answers

It looks like you're using a custom Hits widget here rather than the out-of-the-box instantsearch.js widget (which is fine).

You're going to want to build you link here in the hit template:

const Hits = ({
  hits
}) => ( <
  table className = "table-auto" > {
    hits.map(hit => ( <
      tbody >

      <
      tr >
      <
      td className = "text-black font-bold"
      key = {
        hit.objectID
      } > {
        hit.title
      } < /td> <
      /tr>

      <
      /tbody>
    ))
  } <
  /table>
);

For instance if you store the URLs in the object records, you could do something like:

{
 <a href="hit.url">hit.title</a>
}

More likely, you'll want to build onClick event using Link. Something like:

<Link
  onClick={() => {
    setIsOpen(false);
  }}
  to={`/product/${hit.objectID}`}
>
  hit.title
</Link>

In either case, just make sure everything you need to build the link (URL, routing IDs, etc.) is embedded in the Algolia records, then just build your links within your hit template as you typically would for your application.

I found the answer:

import router, {useRouter} from "next/router";

import { connectHits } from 'react-instantsearch-dom';

const Hits = ({ hits }) => (
 
 <table className="table-auto">
    {hits.map(hit => (
     <tbody>
     
     <tr>
     <td className="text-black font-bold" key={hit.objectID} onClick={() => router.push(hit.url)}>{hit.title}</td>
     </tr>
    
     </tbody>
    ))}
  </table>
);








const CustomHits = connectHits(Hits);

In your search records (I used the Algolia index to make mine), you just need to code in a url in your JSON record and then use react router on the hit.url attribute!

Related