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

# ais-sort-by

> 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>;

```vue Signature theme={"system"}
<ais-sort-by
  :items="object[]" // Optional parameters
  :transform-items="function"
  :class-names="object"
/>
```

## Import

<Tabs>
  <Tab title="Component">
    To ensure optimal bundle sizes,
    see [Optimize build size](/doc/guides/building-search-ui/going-further/improve-performance/vue#optimize-build-size).

    ```js Vue icon=code theme={"system"}
    import { AisSortBy } from "vue-instantsearch";
    // Use "vue-instantsearch/vue3/es" for Vue 3

    export default {
      components: {
        AisSortBy
      },
      // ...
    };
    ```
  </Tab>

  <Tab title="Plugin">
    This imports all widgets, even the ones you don't use.
    For more information, see [Get started with Vue InstantSearch](/doc/guides/building-search-ui/getting-started/vue).

    ```js JavaScript icon="code" theme={"system"}
    import Vue from "vue";
    import InstantSearch from "vue-instantsearch";
    // Use "vue-instantsearch/vue3/es" for Vue 3

    Vue.use(InstantSearch);
    ```
  </Tab>
</Tabs>

<Card title="See this widget in action" icon="monitor-play" href="https://instantsearchjs.netlify.app/stories/vue/?selectedKind=ais-sort-by" 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 />.

## Examples

```vue Vue icon=code theme={"system"}
<ais-sort-by
  :items="[
    { value: 'instant_search', label: 'Featured' },
    { value: 'instant_search_price_asc', label: 'Price asc.' },
    { value: 'instant_search_price_desc', label: 'Price desc.' },
  ]"
/>
```

## Props

<ParamField body="items" type="object[]" required>
  The list of indices to search in, with each item:

  * `label: string`. The label of the index to display.
  * `value: string`. The name of the index to target.

  ```vue Vue icon=code theme={"system"}
  <ais-sort-by
    :items="[
      { value: 'instant_search', label: 'Featured' },
      { value: 'instant_search_price_asc', label: 'Price asc.' },
      { value: 'instant_search_price_desc', label: 'Price desc.' },
    ]"
  />
  ```
</ParamField>

<ParamField body="transform-items" type="function" default="items => items">
  <TranformItems />

  <Note>
    To [prevent creating infinite loops](https://support.algolia.com/hc/en-us/articles/4406511683217-Vue-InstantSearch-How-do-I-prevent-infinite-loops),
    avoid passing arrays, objects, or functions directly in the template.
    These values aren't referentially equal on each render,
    which causes the widget to re-register every time.
    Instead, define them in your component's `data` option and reference them in the template.
  </Note>

  ```vue Vue icon=code theme={"system"}
  <template>
    <!-- ... -->
    <ais-sort-by
      [...]
      :transform-items="transformItems"
    />
  </template>

  <script>
    export default {
      methods: {
        transformItems(items) {
          return items.map(item => ({
            ...item,
            label: item.label.toUpperCase(),
          }));
        },

        // or, combined with results
        transformItems(items, { results }) {
          return results?.nbPages < 4
            ? items.filter(item => item.value === 'instant_search')
            : items;
        },
      },
    };
  </script>
  ```
</ParamField>

<ParamField body="class-names" type="object" default="{}">
  The [CSS classes you can override](/doc/guides/building-search-ui/widgets/customize-an-existing-widget/vue#style-your-widgets):

  * `ais-SortBy`. The root of the widget
  * `ais-SortBy-select`. The `select` element.
  * `ais-SortBy-option`. The `option` element of the `select`.

  ```vue Vue icon=code theme={"system"}
  <ais-sort-by
    [...]
    :class-names="{
      'ais-SortBy': 'MyCustomSortBy',
      'ais-SortBy-select': 'MyCustomSortBySelect',
      // ...
    }"
  />
  ```
</ParamField>

## Customize the UI

<ParamField body="default">
  The slot to override the complete DOM output of the widget.

  When you implement this slot,
  none of the other slots will change the output,
  as the default slot surrounds them.

  **Scope**

  * `items: object[]`. The list of items the widget can display.
  * `currentRefinement: string`. The currently applied refinement.
  * `canRefine: boolean`. Whether a refinement can be applied.
  * `refine: (value: string) => void`. The function to call with the next value of the index name.

  Where each item is an `object` containing:

  * `label: string`. The label of the index to display.
  * `value: string`. The name of the index to target.

  ```vue Vue icon=code theme={"system"}
  <ais-sort-by
    :items="[
      { value: 'instant_search', label: 'Featured' },
      { value: 'instant_search_price_asc', label: 'Price asc.' },
      { value: 'instant_search_price_desc', label: 'Price desc.' },
    ]"
  >
    <template v-slot="{ items, currentRefinement, refine }">
      <ul>
        <li v-for="item in items" :key="item.value" :value="item.value">
          <a
            href="#"
            :style="{ fontWeight: item.value === currentRefinement ? 'bold' : '' }"
            @click.prevent="refine(item.value)"
          >
            {{ item.label }}
          </a>
        </li>
      </ul>
    </template>
  </ais-sort-by>
  ```
</ParamField>

## HTML output

```html HTML icon=code-xml theme={"system"}
<div class="ais-SortBy">
  <select class="ais-SortBy-select">
    <option class="ais-SortBy-option" value="instant_search">Featured</option>
    <option class="ais-SortBy-option" value="instant_search_price_asc">
      Price asc.
    </option>
    <option class="ais-SortBy-option" value="instant_search_price_desc">
      Price desc.
    </option>
  </select>
</div>
```
