Skip to main content
The useHits hook provides access to the search results (hits) from Algolia.

Import

import { useHits } from 'react-instantsearch';

Parameters

escapeHTML
boolean
default:"true"
Whether to escape HTML tags in hit string values.
const { items } = useHits({ escapeHTML: false });
transformItems
(items: Hit[]) => Hit[]
Function to transform the hits before rendering.
const { items } = useHits({
  transformItems: (items) => 
    items.map((item) => ({
      ...item,
      formattedPrice: `$${item.price.toFixed(2)}`,
    })),
});

Returns

items
Hit[]
The array of hits from the current search.
const { items } = useHits();
items.forEach((item) => {
  console.log(item.objectID, item.name);
});
hits
Hit[]
Alias for items (deprecated).
Use items instead. The hits property is deprecated.
results
SearchResults | undefined
The complete search results object from Algolia.
const { results } = useHits();
console.log(results?.nbHits);
console.log(results?.processingTimeMS);
banner
Banner | undefined
The banner to display above the hits (if configured).
const { banner } = useHits();
if (banner) {
  return <img src={banner.image.urls[0].url} alt={banner.image.title} />;
}
sendEvent
SendEventForHits
Function to send events to the Insights API.
const { items, sendEvent } = useHits();

sendEvent('click', items[0], 'Product Clicked');
bindEvent
BindEventForHits
Function to bind Insights events to HTML elements.
const { items, bindEvent } = useHits();

<div {...bindEvent('click', items[0], 'Product Clicked')}>
  {/* ... */}
</div>

Examples

Basic Hits Display

import { useHits } from 'react-instantsearch';

function CustomHits() {
  const { items } = useHits();

  return (
    <div className="hits">
      {items.map((item) => (
        <div key={item.objectID} className="hit">
          <img src={item.image} alt={item.name} />
          <h3>{item.name}</h3>
          <p>{item.description}</p>
          <span>${item.price}</span>
        </div>
      ))}
    </div>
  );
}

With TypeScript

import { useHits } from 'react-instantsearch';
import type { Hit } from 'instantsearch.js';

interface Product {
  objectID: string;
  name: string;
  description: string;
  price: number;
  image: string;
  brand: string;
}

function ProductHits() {
  const { items } = useHits<Product>();

  return (
    <div className="products">
      {items.map((item) => (
        <div key={item.objectID}>
          <img src={item.image} alt={item.name} />
          <h3>{item.name}</h3>
          <p>{item.brand}</p>
          <p>${item.price.toFixed(2)}</p>
        </div>
      ))}
    </div>
  );
}

With Highlighting

import { useHits, Highlight } from 'react-instantsearch';

function HighlightedHits() {
  const { items } = useHits();

  return (
    <div className="hits">
      {items.map((item) => (
        <div key={item.objectID}>
          <h3>
            <Highlight attribute="name" hit={item} />
          </h3>
          <p>
            <Highlight attribute="description" hit={item} />
          </p>
        </div>
      ))}
    </div>
  );
}

Transform Items

import { useHits } from 'react-instantsearch';

function TransformedHits() {
  const { items } = useHits({
    transformItems: (items) =>
      items.map((item) => ({
        ...item,
        // Add computed fields
        formattedPrice: `$${item.price.toFixed(2)}`,
        // Add discount calculation
        discountPrice: item.discount 
          ? item.price * (1 - item.discount / 100)
          : item.price,
      })),
  });

  return (
    <div className="hits">
      {items.map((item) => (
        <div key={item.objectID}>
          <h3>{item.name}</h3>
          {item.discount ? (
            <>
              <span className="original-price">{item.formattedPrice}</span>
              <span className="discount-price">
                ${item.discountPrice.toFixed(2)}
              </span>
            </>
          ) : (
            <span>{item.formattedPrice}</span>
          )}
        </div>
      ))}
    </div>
  );
}

With Insights Events

import { useHits } from 'react-instantsearch';

function HitsWithInsights() {
  const { items, sendEvent } = useHits();

  const handleClick = (item) => {
    sendEvent('click', item, 'Product Clicked');
    // Navigate to product page
    window.location.href = `/products/${item.objectID}`;
  };

  return (
    <div className="hits">
      {items.map((item) => (
        <div 
          key={item.objectID}
          onClick={() => handleClick(item)}
          style={{ cursor: 'pointer' }}
        >
          <h3>{item.name}</h3>
          <p>{item.description}</p>
        </div>
      ))}
    </div>
  );
}

With Empty State

import { useHits } from 'react-instantsearch';

function HitsWithEmptyState() {
  const { items } = useHits();

  if (items.length === 0) {
    return (
      <div className="empty-state">
        <h3>No results found</h3>
        <p>Try adjusting your search or filters</p>
      </div>
    );
  }

  return (
    <div className="hits">
      {items.map((item) => (
        <div key={item.objectID}>
          {/* ... */}
        </div>
      ))}
    </div>
  );
}

With Results Metadata

import { useHits } from 'react-instantsearch';

function HitsWithMetadata() {
  const { items, results } = useHits();

  return (
    <div>
      <div className="results-info">
        <p>
          {results?.nbHits.toLocaleString()} results found in{' '}
          {results?.processingTimeMS}ms
        </p>
      </div>
      <div className="hits">
        {items.map((item) => (
          <div key={item.objectID}>
            {/* ... */}
          </div>
        ))}
      </div>
    </div>
  );
}

Grid Layout

import { useHits } from 'react-instantsearch';

function GridHits() {
  const { items } = useHits();

  return (
    <div className="hits-grid">
      {items.map((item) => (
        <div key={item.objectID} className="hit-card">
          <div className="hit-image">
            <img src={item.image} alt={item.name} />
          </div>
          <div className="hit-content">
            <h3>{item.name}</h3>
            <p className="brand">{item.brand}</p>
            <div className="hit-footer">
              <span className="price">${item.price}</span>
              {item.rating && (
                <span className="rating">{item.rating}</span>
              )}
            </div>
          </div>
        </div>
      ))}
    </div>
  );
}

With Banner

import { useHits } from 'react-instantsearch';

function HitsWithBanner() {
  const { items, banner } = useHits();

  return (
    <div>
      {banner && (
        <div className="banner">
          <a href={banner.link.url}>
            <img 
              src={banner.image.urls[0].url} 
              alt={banner.image.title}
            />
          </a>
        </div>
      )}
      <div className="hits">
        {items.map((item) => (
          <div key={item.objectID}>
            {/* ... */}
          </div>
        ))}
      </div>
    </div>
  );
}

Build docs developers (and LLMs) love