> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Breadcrumb

> Shows a navigation path based on hierarchical facets.

export const Records = () => <Tooltip tip="A record is a searchable object in an Algolia index. Each record consists of named attributes." cta="Algolia records" href="/doc/guides/sending-and-managing-data/prepare-your-data#algolia-records">
    records
  </Tooltip>;

<Note>
  This is the **React InstantSearch v7** documentation.
  If you're upgrading from v6, see the [upgrade guide](/doc/guides/building-search-ui/upgrade-guides/react/#migrate-from-react-instantsearch-v6-to-react-instantsearch-v7).
  If you were using React InstantSearch Hooks,
  this v7 documentation applies—just check for [necessary changes](/doc/guides/building-search-ui/upgrade-guides/react/#migrate-from-react-instantsearch-hooks-to-react-instantsearch-v7).
  To continue using v6, you can find the [archived documentation](https://algolia.com/old-docs/deprecated/instantsearch/react/v6/api-reference/instantsearch/).
</Note>

```tsx Signature theme={"system"}
<Breadcrumb
  attributes={string[]}
  // Optional parameters
  rootPath={string}
  separator={string}
  transformItems={function}
  classNames={object}
  translations={object}
  ...props={ComponentProps<'div'>}
/>
```

## Import

```jsx JavaScript icon=code theme={"system"}
import { Breadcrumb } from "react-instantsearch";
```

<Card title="See this widget in action" icon="monitor-play" href="https://instantsearchjs.netlify.app/stories/js/?path=/story/metadata-breadcrumb--default" horizontal>
  Preview this widget and its behavior.
</Card>

## About this widget

`<Breadcrumb>` is a widget that displays navigation links to see where the current page is in relation to the facet's hierarchy.

It reduces the number of actions a user needs to take to get to a higher-level page and improves the discoverability of the app or website's sections and pages.
It's commonly used for websites with lot of data, organized into categories with subcategories.

<Tip>You can also create your own UI with [`useBreadcrumb`](#hook).</Tip>

### Requirements

The objects to use in the breadcrumb must follow this structure:

```json JSON icon=braces theme={"system"}
[
  {
    "objectID": "321432",
    "name": "lemon",
    "categories.lvl0": "products",
    "categories.lvl1": "products > fruits"
  },
  {
    "objectID": "8976987",
    "name": "orange",
    "categories.lvl0": "products",
    "categories.lvl1": "products > fruits"
  }
]
```

It's also possible to provide more than one path for each level:

```json JSON icon=braces theme={"system"}
[
  {
    "objectID": "321432",
    "name": "lemon",
    "categories.lvl0": ["products", "goods"],
    "categories.lvl1": ["products > fruits", "goods > to eat"]
  }
]
```

To create a hierarchical menu:

1. Decide on an appropriate [facet hierarchy](/doc/guides/managing-results/refine-results/faceting#hierarchical-facets)
2. Determine your [`attributes`](#param-attributes) for faceting from the [dashboard](/doc/guides/managing-results/refine-results/faceting/how-to/declaring-attributes-for-faceting-with-dashboard) or with an [API client](/doc/guides/managing-results/refine-results/faceting/how-to/declaring-attributes-for-faceting)
3. Display the UI with the hierarchical menu widget.

For more information, see [Facet display](/doc/guides/building-search-ui/ui-and-ux-patterns/facet-display/react).
By default, the separator is `>` (with spaces),
but you can use a different one by using the [separator](#param-separator) option.

If there is also a [`<HierarchicalMenu>`](/doc/api-reference/widgets/hierarchical-menu/react) on the page,
it must follow the same configuration.

## Examples

```jsx JavaScript icon=code theme={"system"}
import React from "react";
import { liteClient as algoliasearch } from "algoliasearch/lite";
import { InstantSearch, Breadcrumb } from "react-instantsearch";

const searchClient = algoliasearch("YourApplicationID", "YourSearchOnlyAPIKey");

function App() {
  return (
    <InstantSearch indexName="instant_search" searchClient={searchClient}>
      <Breadcrumb
        attributes={["categories.lvl0", "categories.lvl1", "categories.lvl2"]}
      />
    </InstantSearch>
  );
}
```

## Props

<ParamField body="attributes" type="string[]" required>
  An array of attributes to generate the breadcrumb.

  ```jsx JavaScript icon=code theme={"system"}
  <Breadcrumb
    attributes={[
      "hierarchicalCategories.lvl0",
      "hierarchicalCategories.lvl1",
      "hierarchicalCategories.lvl2",
    ]}
  />;
  ```
</ParamField>

<ParamField body="rootPath" type="string">
  The path to use if the first level isn't the root level.

  Make sure to also include the root path in your [UI state](/doc/api-reference/widgets/ui-state/react),
  for example, by setting [`initialUiState`](/doc/api-reference/widgets/instantsearch/react#param-initial-ui-state)
  or calling [`setUiState`](/doc/api-reference/widgets/use-instantsearch/react#param-set-ui-state).

  ```jsx JavaScript icon=code theme={"system"}
  <InstantSearch
    // ...
    initialUiState={{
      YourIndexName: {
        // breadcrumbs share their UI state with hierarchical menus
        hierarchicalMenu: {
          "hierarchicalCategories.lvl0": ["Audio"],
        },
      },
    }}
  >
    <Breadcrumb
      // ...
      rootPath="Audio"
    />
  </InstantSearch>;
  ```
</ParamField>

<ParamField body="separator" type="string" default=" > ">
  The level separator used in the <Records />.

  ```jsx JavaScript icon=code theme={"system"}
  <Breadcrumb
    // ...
    separator=" / "
  />;
  ```
</ParamField>

<ParamField body="transformItems" type="(items: object[], metadata: { results: SearchResults }) => object[]">
  A function that receives the list of items before they are displayed.
  It should return a new array with the same structure.
  Use this to transform, filter, or reorder the items.

  The function also has access to the full `results` data,
  including all standard [response parameters](/doc/guides/building-search-ui/going-further/backend-search/in-depth/understanding-the-api-response/)
  and [parameters from the helper](https://community.algolia.com/algoliasearch-helper-js/reference.html#query-parameters),
  such as `disjunctiveFacetsRefinements`.

  <CodeGroup>
    ```jsx JavaScript theme={"system"}
    const transformItems = (items) => {
      return items.map((item) => ({
        ...item,
        label: item.label.toUpperCase(),
      }));
    };

    function Search() {
      return (
        <Breadcrumb
          // ...
          transformItems={transformItems}
        />
      );
    }
    ```

    ```tsx TypeScript theme={"system"}
    import type { BreadcrumbProps } from "react-instantsearch";

    const transformItems: BreadcrumbProps["transformItems"] = (items) => {
      return items.map((item) => ({
        ...item,
        label: item.label.toUpperCase(),
      }));
    };

    function Search() {
      return (
        <Breadcrumb
          // ...
          transformItems={transformItems}
        />
      );
    }
    ```
  </CodeGroup>
</ParamField>

<ParamField body="classNames" type="Partial<BreadcrumbClassNames>">
  The [CSS classes you can override](/doc/guides/building-search-ui/widgets/customize-an-existing-widget/react#style-your-widgets) and pass to the widget's elements.
  It's useful to style widgets with class-based CSS frameworks like [Bootstrap](https://getbootstrap.com) or [Tailwind CSS](https://tailwindcss.com).

  * `root`. The root element of the widget.
  * `noRefinementRoot`. The root element when there are no refinements.
  * `list`. The list element.
  * `item`. Each item element.
  * `selectedItem`. The selected item element.
  * `separator`. The separator between items.
  * `link`. The link of each item.

  ```jsx JavaScript icon=code theme={"system"}
  <Breadcrumb
    // ...
    classNames={{
      root: "MyBreadcrumb",
      item: "MyBreadcrumbItem MyBreadcrumbItem--subclass",
    }}
  />;
  ```
</ParamField>

<ParamField body="translations" type="Partial<BreadcrumbTranslations>">
  A dictionary of translations to customize the UI text and support internationalization.

  * `rootElementText`. The text for the breadcrumb's starting point (for example, "Home page").

  ```jsx JavaScript icon=code theme={"system"}
  <Breadcrumb
    // ...
    translations={{
      rootElementText: "Index",
    }}
  />;
  ```
</ParamField>

<ParamField body="...props" type="React.ComponentProps<'div'>">
  Any `<div>` prop to forward to the root element of the widget.

  ```jsx JavaScript icon=code theme={"system"}
  <Breadcrumb
    // ...
    className="MyCustomBreadcrumb"
    title="My custom title"
  />;
  ```
</ParamField>

## Hook

React InstantSearch lets you create your own UI for the `<Breadcrumb>` widget with `useBreadcrumb`.
Hooks provide APIs to access the widget state and interact with InstantSearch.

The `useBreadcrumb` Hook accepts [parameters](#parameters) and returns [APIs](#hook).
It must be used inside the [`<InstantSearch>`](/doc/api-reference/widgets/instantsearch/react) component.

### Usage

First, create your React component:

```jsx JavaScript icon=code theme={"system"}
import { useBreadcrumb } from "react-instantsearch";

function CustomBreadcrumb(props) {
  const { items, canRefine, refine, createURL } = useBreadcrumb(props);

  return <>{/* Your JSX */}</>;
}
```

Then, render the widget:

```jsx JavaScript icon=code theme={"system"}
<CustomBreadcrumb {...props} />;
```

### Parameters

Hooks accept parameters. You can either pass them manually or forward props from a custom component.

<Note>
  When passing functions to Hooks, ensure stable references to prevent unnecessary re-renders.
  Use [`useCallback()`](https://reactjs.org/docs/hooks-reference.html#usecallback) for memoization.
  Arrays and objects are automatically memoized.
</Note>

<ParamField body="attributes" type="string[]" required>
  An array of attributes to generate the breadcrumb.

  ```js JavaScript icon=code theme={"system"}
  const breadcrumbApi = useBreadcrumb({
    attributes: [
      "hierarchicalCategories.lvl0",
      "hierarchicalCategories.lvl1",
      "hierarchicalCategories.lvl2",
    ],
  });
  ```
</ParamField>

<ParamField body="rootPath" type="string">
  The path to use if the first level isn't the root level.

  Make sure to also include the root path in your [UI state](/doc/api-reference/widgets/ui-state/react),
  for example, by setting [`initialUiState`](/doc/api-reference/widgets/instantsearch/react#param-initial-ui-state)
  or calling [`setUiState`](/doc/api-reference/widgets/use-instantsearch/react#param-set-ui-state).

  ```js JavaScript icon=code theme={"system"}
  const breadcrumbApi = useBreadcrumb({
    // ...
    rootPath: "Audio",
  });
  ```
</ParamField>

<ParamField body="separator" type="string" default=" > ">
  The level separator used in the records.

  ```js JavaScript icon=code theme={"system"}
  const breadcrumbApi = useBreadcrumb({
    // ...
    separator: " / ",
  });
  ```
</ParamField>

<ParamField body="transformItems" type="(items: object[], metadata: { results: SearchResults }) => object[]">
  A function that receives the list of items before they are displayed.
  It should return a new array with the same structure.
  Use this to transform, filter, or reorder the items.

  The function also has access to the full `results` data,
  including all standard [response parameters](/doc/guides/building-search-ui/going-further/backend-search/in-depth/understanding-the-api-response/)
  and [parameters from the helper](https://community.algolia.com/algoliasearch-helper-js/reference.html#query-parameters),
  such as `disjunctiveFacetsRefinements`.

  <CodeGroup>
    ```jsx JavaScript theme={"system"}
    const transformItems = (items) => {
      return items.map((item) => ({
        ...item,
        label: item.label.toUpperCase(),
      }));
    };

    function Breadcrumb() {
      const breadcrumbApi = useBreadcrumb({
        // ...
        transformItems,
      });

      return <>{/* Your JSX */}</>;
    }
    ```

    ```tsx TypeScript theme={"system"}
    import type { UseBreadcrumbProps } from "react-instantsearch";

    const transformItems: UseBreadcrumbProps["transformItems"] = (items) => {
      return items.map((item) => ({
        ...item,
        label: item.label.toUpperCase(),
      }));
    };

    function Breadcrumb() {
      const breadcrumbApi = useBreadcrumb({
        // ...
        transformItems,
      });

      return <>{/* Your JSX */}</>;
    }
    ```
  </CodeGroup>
</ParamField>

### APIs

<ParamField body="items" type="BreadcrumbItem[]">
  The list of available options, with each option:

  * `label: string`. The label of the category or subcategory.
  * `value: string`. The value of breadcrumb item.

  ```ts TypeScript icon=code theme={"system"}
  type BreadcrumbItem = {
    value: string;
    label: string;
  };
  ```
</ParamField>

<ParamField body="canRefine" type="boolean">
  Indicates if search state can be refined.
</ParamField>

<ParamField body="refine" type="(value: string  |  null) => string">
  Sets the path of the hierarchical filter and triggers a new search.
</ParamField>

<ParamField body="createURL" type="(value: string  |  null) => string">
  Generates a URL of the next state of a clicked item. The special value `null` is used for the root item of the breadcrumb and returns an empty URL.
</ParamField>

### Example

<CodeGroup>
  ```jsx JavaScript theme={"system"}
  import React from "react";
  import { useBreadcrumb } from "react-instantsearch";

  function CustomBreadcrumb(props) {
    const { items, refine, createURL } = useBreadcrumb(props);

    function createOnClick(value) {
      return function onClick(event) {
        if (!isModifierClick(event)) {
          event.preventDefault();
          refine(value);
        }
      };
    }

    return (
      <ul>
        <li>
          <a href={createURL(null)} onClick={createOnClick(null)}>
            Home
          </a>
        </li>

        {items.map((item, index) => {
          const isLast = index === items.length - 1;

            <li key={index}>
              <span aria-hidden="true">&gt;</span>

              {isLast ? (
                item.label
              ) : (
                <a
                  href={createURL(item.value)}
                  onClick={createOnClick(item.value)}
                >
                  {item.label}
                </a>
              )}
            </li>
          );
        })}
      </ul>
    );
  }

  function isModifierClick(event) {
    const isMiddleClick = event.button === 1;
    return Boolean(
      isMiddleClick ||
        event.altKey ||
        event.ctrlKey ||
        event.metaKey ||
        event.shiftKey
    );
  }
  ```

  ```tsx TypeScript theme={"system"}
  import React from 'react';
  import { useBreadcrumb, UseBreadcrumbProps } from 'react-instantsearch';

  type BreadcrumbItem = ReturnType<typeof useBreadcrumb>['items'][number];

  function CustomBreadcrumb(props: UseBreadcrumbProps) {
    const { items, refine, createURL } = useBreadcrumb(props);
    
    function createOnClick(value: BreadcrumbItem['value']) {
      return function onClick(
        event: React.MouseEvent<HTMLAnchorElement, MouseEvent>,
      ) {
        if (!isModifierClick(event)) {
          event.preventDefault();
          refine(value);
        }
      };
    }

    return (
      <ul>
        <li>
          <a href={createURL(null)} onClick={createOnClick(null)}>
            Home
          </a>
        </li>

        {items.map((item, index) => {
          const isLast = index === items.length - 1;

          return (
            <li key={index}>
              <span aria-hidden="true">&gt;</span>

              {isLast ? (
                item.label
              ) : (
                <a
                  href={createURL(item.value)}
                  onClick={createOnClick(item.value)}
                >
                  {item.label}
                </a>
              )}
            </li>
          );
        })}
      </ul>
    );
  }

  function isModifierClick(event: React.MouseEvent) {
    const isMiddleClick = event.button === 1;
    return Boolean(
      isMiddleClick ||
        event.altKey ||
        event.ctrlKey ||
        event.metaKey ||
        event.shiftKey
    );
  }
  ```
</CodeGroup>
