Automatically displays refinement widgets based on the attributes returned by Algolia’s dynamic faceting feature.
Usage
import instantsearch from 'instantsearch.js';
import { dynamicWidgets, refinementList, menu } from 'instantsearch.js/es/widgets';
const search = instantsearch({
indexName: 'instant_search',
searchClient
});
search.addWidgets([
dynamicWidgets({
container: '#dynamic-widgets',
widgets: [
container => refinementList({
container,
attribute: 'brand'
}),
container => menu({
container,
attribute: 'category'
})
]
})
]);
search.start();
Requirements
Enable dynamic faceting in your Algolia index settings by setting the attributesToRetrieve to ['*'] and configuring maxValuesPerFacet.
Parameters
container
string | HTMLElement
required
CSS selector or HTMLElement to insert the widget.
Array of widget creator functions. Each function receives a container element and should return a widget.Array<(container: HTMLElement) => Widget>
Function to create a fallback widget when an attribute isn’t found in the widgets array.({ attribute: string, container: HTMLElement }) => Widget
Array of facets to apply dynamic widgets on. By default, all returned facets are used.
Maximum number of values to retrieve per facet.
Function to transform the list of attributes to render.(items: string[]) => string[]
Examples
dynamicWidgets({
container: '#dynamic-widgets',
widgets: [
container => refinementList({
container,
attribute: 'brand'
}),
container => refinementList({
container,
attribute: 'color'
}),
container => menu({
container,
attribute: 'category'
})
]
});
dynamicWidgets({
container: '#dynamic-widgets',
widgets: [
container => refinementList({
container,
attribute: 'brand'
})
],
fallbackWidget({ attribute, container }) {
return refinementList({
container,
attribute,
limit: 5
});
}
});
With panel wrapper
import { panel } from 'instantsearch.js/es/widgets';
dynamicWidgets({
container: '#dynamic-widgets',
widgets: [
container => panel({
templates: { header: 'Brand' }
})(refinementList)({
container,
attribute: 'brand'
}),
container => panel({
templates: { header: 'Category' }
})(menu)({
container,
attribute: 'category'
})
]
});
Filter attributes
dynamicWidgets({
container: '#dynamic-widgets',
transformItems(attributes) {
// Only show specific attributes
const allowedAttributes = ['brand', 'category', 'color'];
return attributes.filter(attr => allowedAttributes.includes(attr));
},
fallbackWidget({ attribute, container }) {
return refinementList({ container, attribute });
}
});
Specific facets
dynamicWidgets({
container: '#dynamic-widgets',
facets: ['brand', 'category', 'size', 'color'],
maxValuesPerFacet: 20,
fallbackWidget({ attribute, container }) {
return refinementList({
container,
attribute,
limit: 10
});
}
});
dynamicWidgets({
container: '#dynamic-widgets',
widgets: [],
fallbackWidget({ attribute, container }) {
// Use different widgets based on attribute type
if (attribute === 'price') {
return rangeSlider({ container, attribute });
}
if (attribute === 'rating') {
return ratingMenu({ container, attribute });
}
return refinementList({ container, attribute });
}
});
HTML output
<div class="ais-DynamicWidgets">
<div class="ais-DynamicWidgets-widget">
<!-- First widget (e.g., brand refinementList) -->
</div>
<div class="ais-DynamicWidgets-widget">
<!-- Second widget (e.g., category menu) -->
</div>
<!-- More widgets based on facetOrdering -->
</div>
Notes
- Widgets are displayed in the order defined by
facetOrdering in your Algolia index.
- The widget automatically shows/hides based on available facets.
- Use with
attributesForFaceting in your index configuration.
- Each widget receives its own container element.