Skip to main content
Signature
<ais-menu-select
  attribute="string"
  // Optional parameters
  :limit="number"
  :sort-by="string[] | function"
  :transform-items="function"
  :class-names="object"
/>

Import

  • Component
  • Plugin
To ensure optimal bundle sizes, see Optimize build size.
Vue
import { AisMenuSelect } from "vue-instantsearch";
// Use "vue-instantsearch/vue3/es" for Vue 3

export default {
  components: {
    AisMenuSelect
  },
  // ...
};

About this widget

The ais-menu-select widget allows a user to select a single value to refine inside a select element.

Requirements

The attribute provided to the widget must be in attributes for faceting, either on the dashboard or using the attributesForFaceting parameter with the API.

Examples

Vue
<ais-menu-select attribute="categories" />

Props

attribute
string
required
The name of the attribute in the record.
Vue
<ais-menu-select attribute="categories" />
limit
number
default:10
The maximum number of values to display.
Vue
<ais-menu-select
  [...]
  :limit="20"
/>
sort-by
string[] | function
How to sort refinements. Must be one or more of the following strings:
  • "count:asc"
  • "count:desc"
  • "name:asc"
  • "name:desc"
  • "isRefined"
It’s also possible to give a function, which receives items two by two, like JavaScript’s Array.sort.If facetOrdering is set for this facet in renderingContent, and no value for sortBy is passed to this widget, facetOrdering is used, and the default order as a fallback.
To prevent creating 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.
Vue
<ais-menu-select :sort-by="['isRefined', 'count:desc']" />
transform-items
function
default:"items => items"
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 and parameters from the helper, such as disjunctiveFacetsRefinements.
Vue
<template>
  <!-- ... -->
  <ais-menu-select :transform-items="transformItems" />
</template>

<script>
export default {
  methods: {
    transformItems(items) {
      return items.map((item) => ({
        ...item,
        label: item.label.toUpperCase(),
      }));
    },
  },
};
</script>
class-names
object
default:"{}"
The CSS classes you can override:
  • .ais-MenuSelect. The root element of the widget
  • .ais-MenuSelect--noRefinement. The root element of the widget with no refinement
  • .ais-MenuSelect-select. Theselect element
  • .ais-MenuSelect-option. The option elements of the select
Vue
<ais-menu-select
  [...]
  :class-names="{
    'ais-MenuSelect': 'MyCustomMenuSelect',
    'ais-MenuSelect-option': 'MyCustomMenuSelectOption',
    // ...
  }"
/>

Customize the UI

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 values applicable to this menu.
  • canRefine: boolean. Can the refinement be applied?
  • refine: (value: string) => void. A function to select a refinement.
  • createURL: (item: string) => string. A function to return a link for this refinement.
  • sendEvent: (eventType: 'click', facetValue: string) => void. The function to send click events.
    • The view event is automatically sent when the facets are rendered.
    • The click event is automatically sent when refine is called.
    To learn more, see the insights middleware.
Where each item is an object containing:
  • value: string. The value of the menu item.
  • label: string. Human-readable value of the menu item.
  • count: number. Number of results matched after a refinement is applied.
  • isRefined: boolean. Indicates if the refinement is applied.
Vue
<ais-menu-select attribute="categories">
  <template v-slot="{ items, canRefine, refine, sendEvent }">
    <select
      :disabled="!canRefine"
      @change="refine($event.currentTarget.value)"
    >
      <option value="">All</option>
      <option
        v-for="item in items"
        :key="item.value"
        :value="item.value"
        :selected="item.isRefined"
      >
        {{ item.label }}
      </option>
    </select>
  </template>
</ais-menu-select>
item
The slot to override the content of an option element. Make sure to use template as the root, since any other elements inside an option are not allowed.Scope
  • item: object. The values applicable to the option.
Where item is an object containing:
  • value: string. The value of the menu item.
  • label: string. Human-readable value of the menu item.
  • count: number. Number of results matched after a refinement is applied.
  • isRefined: boolean. Indicates if the refinement is applied.
Vue
<ais-menu-select attribute="categories">
  <template v-slot:item="{ item }">
    {{ item.label }}
  </template>
</ais-menu-select>
defaultOption
The slot to override the content of the option element which selects “all items”. Make sure to use template as the root, since any other elements inside an option are not allowed.ScopeNo scope is provided to this slot.
Vue
<ais-menu-select attribute="categories">
  <template v-slot:defaultOption>See all categories</template>
</ais-menu-select>

HTML output

HTML
<div class="ais-MenuSelect">
  <select class="ais-MenuSelect-select">
    <option class="ais-Menu-option">Apple (50)</option>
    <!-- more items -->
  </select>
</div>
If SEO is important for your search page, ensure that your custom HTML is optimized for search engines:
  • Use <a> tags with href attributes to allow search engine bots to follow links.
  • Use semantic HTML and include structured data when relevant.
For more guidance, see the SEO checklist.
I