API Reference / Vue InstantSearch Widgets / ais-hierarchical-menu
Apr. 24, 2019

ais-hierarchical-menu

Widget signature
<ais-hierarchical-menu
  :attributes="string[]"
  // Optional parameters
  :limit="number"
  :show-more="boolean"
  :show-more-limit="number"
  separator="string"
  root-path="string"
  :show-parent-level="boolean"
  :sort-by="string[]|function"
  :transform-items="function"
  :class-names="object"
/>

About this widget

The ais-hierarchical-menu widget is used to create a navigation based on a hierarchy of facet attributes. It is commonly used for categories with subcategories.

Requirements

The objects to use in the hierarchical menu must follow this structure:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
  {
    "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:

1
2
3
4
5
6
7
8
[
  {
    "objectID": "321432",
    "name": "lemon",
    "categories.lvl0": ["products", "goods"],
    "categories.lvl1": ["products > fruits", "goods > to eat"]
  }
]

The attributes passed to the attributes prop must be added in attributes for faceting, either on the dashboard or using attributesForFaceting with the API. By default, the separator we expect is > (with spaces) but you can use a different one by using the separator option.

Examples

1
2
3
4
5
6
7
8
<ais-hierarchical-menu
  :attributes="[
    'categories.lvl0',
    'categories.lvl1',
    'categories.lvl2',
    'categories.lvl3',
  ]"
/>

Props

attributes
type: string[]
Required

The name of the attributes to generate the menu with.

1
2
3
4
5
6
7
8
<ais-hierarchical-menu
  :attributes="[
    'categories.lvl0',
    'categories.lvl1',
    'categories.lvl2',
    'categories.lvl3',
  ]"
/>
limit
type: number
default: 10
Optional

The minimum number of facet values to retrieve.

1
2
3
4
<ais-hierarchical-menu
  [...]
  :limit="20"
/>
show-more
type: boolean
default: false
Optional

Whether to display a button that expands the number of items.

1
2
3
4
<ais-hierarchical-menu
  [...]
  show-more
/>
show-more-limit
type: number
default: 20
Optional

The maximum number of displayed items (only used when show-more is set to true).

1
2
3
4
<ais-hierarchical-menu
  [...]
  :show-more-limit="30"
/>
separator
type: string
default: >
Optional

The level separator used in the records.

1
2
3
4
<ais-hierarchical-menu
  [...]
  separator="-"
/>
root-path
type: string
Optional

The prefix path to use if the first level is not the root level.

1
2
3
4
<ais-hierarchical-menu
  [...]
  root-path="Audio > Home Audio"
/>
show-parent-level
type: boolean
default: true
Optional

Whether to show the siblings of the selected parent level of the current refined value.

1
2
3
4
<ais-hierarchical-menu
  [...]
  :show-parent-level="false"
/>
sort-by
type: string[]|function
default: ["name:asc", "count:desc"]

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.

1
2
3
4
<ais-hierarchical-menu
  [...]
  :sort-by="['isRefined', 'count:desc']"
/>
transform-items
type: function
Optional

Modifies the items being displayed, for example, to filter or sort them. It takes items as argument and expects them back in return.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  <template>
    <!-- ... -->
    <ais-hierarchical-menu
      [...]
      :transform-items="transformItems"
    />
  </template>

  <script>
    export default {
      methods: {
        transformItems(items) {
          return items.map(item => ({
            ...item,
            label: item.label.toUpperCase(),
          }));
        },
      },
    };
  </script>
class-names
type: object
Optional

The CSS classes to override.

  • ais-HierarchicalMenu: the root element of the widget
  • ais-HierarchicalMenu--noRefinement: the root element of the widget with no refinement.
  • ais-HierarchicalMenu-list: the list of menu items.
  • ais-HierarchicalMenu-list--child: the child list of menu items.
  • ais-HierarchicalMenu-list--lvl0: the level 0 list of menu items.
  • ais-HierarchicalMenu-list--lvl1: the level 1 list of menu items (and so on).
  • ais-HierarchicalMenu-item: the menu list item.
  • ais-HierarchicalMenu-item--selected: the selected menu list item.
  • ais-HierarchicalMenu-item--parent: the menu list item containing children.
  • ais-HierarchicalMenu-link: the clickable menu element.
  • ais-HierarchicalMenu-label: the label of each item.
  • ais-HierarchicalMenu-count: the count of each item.
  • ais-HierarchicalMenu-showMore: the button used to display more categories.
  • ais-HierarchicalMenu-showMore--disabled: the disabled button used to display more categories.
1
2
3
4
5
6
7
<ais-hierarchical-menu
  [...]
  :class-names="{
    'ais-HierarchicalMenu': 'MyCustomHierarchicalMenu',
    'ais-HierarchicalMenu-list': 'MyCustomHierarchicalMenuList',
  }"
/>

Customize the UI

default

The slot to override the complete DOM output of the widget.

Scope

  • items: object[]: the list of available items.
  • canToggleShowMore: boolean: whether or not the “Show more” button can be clicked.
  • isShowingMore: boolean: whether or not the list is expanded.
  • refine: (value: string) => void: sets the path of the hierarchical filter and triggers a new search.
  • createURL: (value: string) => string: the function to generate a URL for the next state.
  • toggleShowMore: () => void: toggles the number of displayed values between limit and show-more-limit.

Where each item is an object containing:

  • label: string: the label of the item.
  • value: string: the value of the item.
  • count: number: the number results matching this value.
  • isRefined: boolean: whether or not the item is selected.
  • data: object[]|null: the list of children for the current item.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<ais-hierarchical-menu
  :attributes="[
    'hierarchicalCategories.lvl0',
    'hierarchicalCategories.lvl1',
    'hierarchicalCategories.lvl2',
    'hierarchicalCategories.lvl3',
  ]"
  show-more
>
  <div
    slot-scope="{
      items,
      canToggleShowMore,
      isShowingMore,
      refine,
      toggleShowMore,
      createURL,
    }"
  >
    <hierarchical-menu-list
      :items="items"
      :refine="refine"
      :createURL="createURL"
    />
    <button
      @click="toggleShowMore()"
      :disabled="!canToggleShowMore"
    >
      {{ isShowingMore ? 'Show less' : 'Show more' }}
    </button>
  </div>
</ais-hierarchical-menu>
showMoreLabel

The slot to override the show more label

Scope

  • isShowingMore: boolean: whether or not the list is expanded.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<ais-hierarchical-menu
  :attributes="[
    'hierarchicalCategories.lvl0',
    'hierarchicalCategories.lvl1',
    'hierarchicalCategories.lvl2',
    'hierarchicalCategories.lvl3',
  ]"
  show-more
>
  <span
    slot="showMoreLabel"
    slot-scope="{ isShowingMore }"
  >
    {{ isShowingMore ? 'Less' : 'More' }}
  </span>
</ais-hierarchical-menu>

If SEO is critical to your search page, your custom HTML markup needs to be parsable:

  • use plain <a> tags with href attributes for search engines bots to follow them,
  • use semantic markup with structured data when relevant, and test it.

Refer to our SEO checklist for building SEO-ready search experiences.

HTML output

Default

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<div class="ais-HierarchicalMenu">
  <ul class="ais-HierarchicalMenu-list ais-HierarchicalMenu-list--lvl0">
    <li class="ais-HierarchicalMenu-item ais-HierarchicalMenu-item--parent ais-HierarchicalMenu-item--selected">
      <a class="ais-HierarchicalMenu-link" href="#">
        <span class="ais-HierarchicalMenu-label">Appliances</span>
        <span class="ais-HierarchicalMenu-count">4,306</span>
      </a>
      <ul class="ais-HierarchicalMenu-list ais-HierarchicalMenu-list--child ais-HierarchicalMenu-list--lvl1">
        <li class="ais-HierarchicalMenu-item ais-HierarchicalMenu-item--parent">
          <a class="ais-HierarchicalMenu-link" href="#">
            <span class="ais-HierarchicalMenu-label">Dishwashers</span>
            <span class="ais-HierarchicalMenu-count">181</span>
          </a>
        </li>
        <li class="ais-HierarchicalMenu-item">
          <a class="ais-HierarchicalMenu-link" href="#">
            <span class="ais-HierarchicalMenu-label">Fans</span>
            <span class="ais-HierarchicalMenu-count">91</span>
          </a>
        </li>
      </ul>
    </li>
    <li class="ais-HierarchicalMenu-item ais-HierarchicalMenu-item--parent">
      <a class="ais-HierarchicalMenu-link" href="#">
        <span class="ais-HierarchicalMenu-label">Audio</span>
        <span class="ais-HierarchicalMenu-count">1,570</span>
      </a>
    </li>
  </ul>
  <button class="ais-HierarchicalMenu-showMore">Show more</button>
</div>

Show more disabled

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<div class="ais-HierarchicalMenu">
  <ul class="ais-HierarchicalMenu-list ais-HierarchicalMenu-list--lvl0">
    <li class="ais-HierarchicalMenu-item ais-HierarchicalMenu-item--parent ais-HierarchicalMenu-item--selected">
      <a class="ais-HierarchicalMenu-link" href="#">
        <span class="ais-HierarchicalMenu-label">Appliances</span>
        <span class="ais-HierarchicalMenu-count">4,306</span>
      </a>
      <ul class="ais-HierarchicalMenu-list ais-HierarchicalMenu-list--child ais-HierarchicalMenu-list--lvl1">
        <li class="ais-HierarchicalMenu-item ais-HierarchicalMenu-item--parent">
          <a class="ais-HierarchicalMenu-link" href="#">
            <span class="ais-HierarchicalMenu-label">Dishwashers</span>
            <span class="ais-HierarchicalMenu-count">181</span>
          </a>
        </li>
        <li class="ais-HierarchicalMenu-item">
          <a class="ais-HierarchicalMenu-link" href="#">
            <span class="ais-HierarchicalMenu-label">Fans</span>
            <span class="ais-HierarchicalMenu-count">91</span>
          </a>
        </li>
      </ul>
    </li>
    <li class="ais-HierarchicalMenu-item ais-HierarchicalMenu-item--parent">
      <a class="ais-HierarchicalMenu-link" href="#">
        <span class="ais-HierarchicalMenu-label">Audio</span>
        <span class="ais-HierarchicalMenu-count">1,570</span>
      </a>
    </li>
  </ul>
  <button class="ais-HierarchicalMenu-showMore ais-HierarchicalMenu-showMore--disabled" disabled>Show more</button>
</div>

Did you find this page helpful?