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

# SortBy

> Shows a list of indices for alternative sorting or ranking of search results.

export const Index = () => <Tooltip tip="An Algolia index is a searchable dataset that consists of records and configuration settings. These settings define how the records are searched and ranked.">
    index
  </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"}
<SortBy
  items={object[]}
  // Optional parameters
  transformItems={function}
  classNames={object}
  ...props={ComponentProps<'div'>}
/>
```

## Import

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

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

## About this widget

This widget displays a list of indices,
allowing a user to change the way hits are sorting
(with [replica indices](/doc/guides/managing-results/refine-results/sorting/how-to/creating-replicas)).
Another common use case for this widget is to let users switch between different indices.

For this widget to work,
you must define all indices that you pass down as options as replicas of the main <Index />.

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

### Requirements

You must set all indices you define in [`items`](#param-items) as [replicas of the main index](/doc/guides/managing-results/refine-results/sorting/how-to/creating-replicas).

## Examples

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

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

function App() {
  return (
    <InstantSearch indexName="instant_search" searchClient={searchClient}>
      <SortBy
        items={[
          { label: "Featured", value: "instant_search" },
          { label: "Price (asc)", value: "instant_search_price_asc" },
          { label: "Price (desc)", value: "instant_search_price_desc" },
        ]}
      />
    </InstantSearch>
  );
}
```

## Props

<ParamField body="items" type="SortByProps['items']" required>
  A list of different indices to choose from.

  ```jsx JavaScript icon=code theme={"system"}
  <SortBy
    items={[
      { label: "Featured", value: "instant_search" },
      { label: "Price (asc)", value: "instant_search_price_asc" },
      { label: "Price (desc)", value: "instant_search_price_desc" },
    ]}
  />;
  ```
</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 (
        <SortBy
          // ...
          transformItems={transformItems}
        />
      );
    }
    ```

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

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

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

<ParamField body="classNames" type="Partial<SortByClassNames>">
  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.
  * `select`. The `select` element.
  * `option`. The `option` element.

  ```jsx JavaScript icon=code theme={"system"}
  <SortBy
    // ...
    classNames={{
      root: "MyCustomSortBy",
      select: "MyCustomSortBySelect MyCustomSortBySelect--subclass",
    }}
  />;
  ```
</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"}
  <SortBy
    // ...
    className="MyCustomSortBy"
    title="My custom title"
  />;
  ```
</ParamField>

## Hook

React InstantSearch let you create your own UI for the `<SortBy>` widget with `useSortBy`.
Hooks provide APIs to access the widget state and interact with InstantSearch.

The `useSortBy` 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 { useSortBy } from "react-instantsearch";

function CustomSortBy(props) {
  const { initialIndex, currentRefinement, options, refine, canRefine } =
    useSortBy(props);

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

Then, render the widget:

```jsx JavaScript icon=code theme={"system"}
<CustomSortBy {...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="items" type="UseSortByProps['items']" required>
  A list of different indices to choose from.

  ```js JavaScript icon=code theme={"system"}
  const sortByApi = useSortBy({
    items: [
      { label: "Featured", value: "instant_search" },
      { label: "Price (asc)", value: "instant_search_price_asc" },
      { label: "Price (desc)", value: "instant_search_price_desc" },
    ],
  });
  ```
</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 SortBy() {
      const sortByApi = useSortBy({
        // ...
        transformItems,
      });

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

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

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

    function SortBy() {
      const sortByApi = useSortBy({
        // ...
        transformItems,
      });

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

### APIs

Hooks return APIs, such as state and functions.
You can use them to build your UI and interact with React InstantSearch.

<ParamField body="initialIndex" type="string">
  The initially selected index.
</ParamField>

<ParamField body="currentRefinement" type="string">
  The currently selected index.
</ParamField>

<ParamField body="options" type="SortByItem[]">
  All the available indices.

  ```ts TypeScript icon=code theme={"system"}
  type SortByItem = {
    /**
     * The name of the index to target.
     */
    value: string;
    /**
     * The label of the index to display.
     */
    label: string;
  };
  ```
</ParamField>

<ParamField body="refine" type="(value: string) => void">
  Switches indices and triggers a new search.
</ParamField>

<ParamField body="canRefine" type="boolean">
  Whether the search can be refined.
</ParamField>

### Example

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

  function SortBy(props) {
    const { currentRefinement, options, refine } = useSortBy(props);

    return (
      <select
        onChange={(event) => refine(event.target.value)}
        value={currentRefinement}
      >
        {options.map((option) => (
          <option key={option.value} value={option.value}>
            {option.label}
          </option>
        ))}
      </select>
    );
  }
  ```

  ```tsx TypeScript theme={"system"}
  import React from "react";
  import { useSortBy, UseSortByProps } from "react-instantsearch";

  function SortBy(props: UseSortByProps) {
    const { currentRefinement, options, refine } = useSortBy(props);

    return (
      <select
        onChange={(event) => refine(event.target.value)}
        value={currentRefinement}
      >
        {options.map((option) => (
          <option key={option.value} value={option.value}>
            {option.label}
          </option>
        ))}
      </select>
    );
  }
  ```
</CodeGroup>
