<Search> Component

A search box and results based on Algolia. Used primarily on documentation websites and learn.

Share
Code Editor
<SearchProvider>
<Search
renderHitContent={({ hit, Highlight }) => <div><p>{hit.description}</p></div>}
resolveHitLink={(hit) => ({ href: { pathname: '/' + hit.objectID, query: { id: hit.__queryID} } })}
placeholder="Search documentation"
/>
</SearchProvider>

Where it's used

0.x.x
Loading 0.x.x releases...
1.x.x
Loading 1.x.x releases...
2.x.x
Loading 2.x.x releases...
3.x.x
Loading 3.x.x releases...
4.x.x
Loading 4.x.x releases...
5.x.x
Loading 5.x.x releases...
6.x.x
Loading 6.x.x releases...

Props

NameDescription
onSubmit
function
Handle search form submission
placeholder
string
Placeholder content within the search box
renderCalloutCta
function
Render function for displaying a small CTA beneath the search results
renderHitContent*
function
Render function for displaying search results. Function returns hit data and a Highlight component in an object as arguments.
resolveHitLink
function
Optional function to transform the results of any given hit. Primarily used to remove /index from resuling urls
showSearchLegend
boolean
Enable the search keyboard legend

More Details on Function Props

renderHitContent

function | ({ hit: object, Highlight: React.Node }) => React.Component | Required

A render function whose result is used to display each query "hit"

Params

resolveHitLink

function | | ( hit: object ) => NextLinkProps | Optional | Default: (hit) => ({ href:`/${hit.objectID}` })

A function whose return value is spread as props to next/link. For more information about the available props, reference the next/link documentation: https://nextjs.org/docs/api-reference/next/link

Params

Environment Variables

This component relies on the presence of the following environment variables to be available client side:

NEXT_PUBLIC_ALGOLIA_APP_ID
NEXT_PUBLIC_ALGOLIA_SEARCH_ONLY_API_KEY
NEXT_PUBLIC_ALGOLIA_INDEX

Providers & Hooks

To use the primary <Search /> component, ensure it exists as a child of the <SearchProvider /> component. For example:

App.jsx

import Search, { SearchProvider } from '@hashicorp/react-search'
 
function App() {
  return (
    <>
      <SearchProvider>
        <Search
          renderHitContent={({hit, Highlight}) => (
            <span className="name">
              <Highlight attribute="name" hit={hit} tagName="span" />
            </span>
          )}
          resolveHitLink={(hit) => ({ href: `/${hit.objectID}` })}
        />
        <ComponentA>
        <ComponentB>
      </SearchProvider>
      <ComponentC__WithoutSearchContext>
    </>
  )
}

Any child component of <SearchProvider /> can utilize the provided useSearch() hook and access search-specific information. For example:

import { useSearch } from '@hashicorp/react-search'
 
function ComponentA() {
  const { query } = useSearch()
 
  return <code>Search query: {query}</code>
}

useSearch()

useSearch() exposes the following values:

  • client (object) - Initialized Algolia client
  • indexName (string) - The name of the Algolia index that search is performed upon
  • initAlgoliaInsights (function) - Required to initialize Algolia
  • isCancelled (boolean) - Indicates if search is currently cancelled or not
  • logClick (function) - Fires an analytics event via the search-insights package
  • query (string) - Current search query
  • setIsCancelled (function) - Setter function that updates the search cancel state
  • setQuery (function) - Setter function that updates the search query

Tools

This package includes a tools.js file that includes Algolia-related Node.js scripts

Usage

const {
  indexDocsContent,
  indexContent,
} = require('@hashicorp/react-search/tools')
/* It's worth noting that you'd only want to use *one* of the two exported functions */

indexDocsContent

function | (config: object) This specific helper function is designed specifically for perfoming search indexing on our various product sites' documentation pages.

config.algoliaConfig: { appId: string, apiKey: string, index: string }

Algolia-related configuration

Default:

{
  apiKey: process.env.ALGOLIA_API_KEY,
  appId: process.env.NEXT_PUBLIC_ALGOLIA_APP_ID,
  index: process.env.NEXT_PUBLIC_ALGOLIA_INDEX,
}
config.contentDir: string

Path to directory that contains the content to be indexed by Algolia

Default: path.join(__dirname, 'pages')

config.filesPattern: string

minimatch-style string to be performed within config.contentDir. The results of this pattern match will determine which files to index.

Default: '**/*.mdx'

config.globOptions: { [k:string]: any }

Additional options to include to the glob match. Available options here

Default: { ignore: path.join(config.contentDir, 'partials/**/*') }

config.frontmatterKeys: string[]

Assuming your search-indexed content includes frontmatter, the keys included in this array will be included as search criteria. They will also be set as searchableAttributes in the index configuration.

Default: ['page_title', 'description']

indexContent

function | (config: object) This generic helper function allows for custom Algolia indexing

config.algoliaConfig: { appId: string, apiKey: string, index: string }

Algolia-related configuration

Default:

{
  apiKey: process.env.ALGOLIA_API_KEY,
  appId: process.env.NEXT_PUBLIC_ALGOLIA_APP_ID,
  index: process.env.NEXT_PUBLIC_ALGOLIA_INDEX,
}
config.getSearchObjects: () => Promise<SearchObject[]>

This function should return an array of objects that will get passed to Algolia's saveObjects function. Each object must have an objectID attribute.

config.settings: { [k:string]: any }

Optional settings object that can be used to configure the given index's settings. It's preferable to configure the index this way rather with the web UI because it keeps our settings in source control.

Ex:

  await indexContent({
    algoliaConfig,
    getSearchObjects,
    settings: {
      searchableAttributes: ['name'],
      attributesForFaceting: ['category'],
    },
  })