The <DynamicWidgets> component automatically renders widgets based on the attributesForFaceting configured in your Algolia index.
Import
import { DynamicWidgets } from 'react-instantsearch';
Props
The widgets to render dynamically. Each child widget must have an attribute or attributes prop.<DynamicWidgets>
<RefinementList attribute="brand" />
<RefinementList attribute="color" />
<Menu attribute="category" />
</DynamicWidgets>
fallbackComponent
ComponentType<{ attribute: string }>
A component to render when an attribute is returned by the API but no corresponding widget is provided in children.<DynamicWidgets
fallbackComponent={({ attribute }) => (
<RefinementList attribute={attribute} />
)}
>
{/* ... */}
</DynamicWidgets>
The maximum number of facet values to retrieve for each facet.<DynamicWidgets maxValuesPerFacet={20}>
{/* ... */}
</DynamicWidgets>
Specific facets to render. By default, all facets configured in the index are rendered.<DynamicWidgets facets={['brand', 'color', 'size']}>
{/* ... */}
</DynamicWidgets>
transformItems
(items: string[]) => string[]
Function to transform the list of attributes to render.<DynamicWidgets
transformItems={(items) =>
items.filter((item) => item !== 'internal_field')
}
>
{/* ... */}
</DynamicWidgets>
Examples
Basic Usage
import { InstantSearch, DynamicWidgets, RefinementList, Menu } from 'react-instantsearch';
import { liteClient as algoliasearch } from 'algoliasearch/lite';
const searchClient = algoliasearch(
'YourApplicationID',
'YourSearchOnlyAPIKey'
);
function App() {
return (
<InstantSearch searchClient={searchClient} indexName="products">
<DynamicWidgets>
<RefinementList attribute="brand" />
<RefinementList attribute="color" />
<Menu attribute="category" />
<RefinementList attribute="size" />
</DynamicWidgets>
</InstantSearch>
);
}
With Fallback Component
function App() {
return (
<InstantSearch searchClient={searchClient} indexName="products">
<DynamicWidgets
fallbackComponent={({ attribute }) => (
<div>
<h3>{attribute}</h3>
<RefinementList attribute={attribute} />
</div>
)}
>
<RefinementList attribute="brand" />
<Menu attribute="category" />
</DynamicWidgets>
</InstantSearch>
);
}
function FacetWidget({ attribute, title }) {
return (
<div className="facet-widget">
<h3>{title}</h3>
<RefinementList attribute={attribute} />
</div>
);
}
function App() {
return (
<InstantSearch searchClient={searchClient} indexName="products">
<DynamicWidgets>
<FacetWidget attribute="brand" title="Brands" />
<FacetWidget attribute="color" title="Colors" />
<FacetWidget attribute="size" title="Sizes" />
</DynamicWidgets>
</InstantSearch>
);
}
Filtering Attributes
function App() {
return (
<InstantSearch searchClient={searchClient} indexName="products">
<DynamicWidgets
facets={['brand', 'color', 'category']}
transformItems={(items) => {
// Only show items that have results
return items.filter((item) =>
!item.startsWith('internal_')
);
}}
>
<RefinementList attribute="brand" />
<RefinementList attribute="color" />
<Menu attribute="category" />
</DynamicWidgets>
</InstantSearch>
);
}
function App() {
return (
<InstantSearch searchClient={searchClient} indexName="products">
<DynamicWidgets
fallbackComponent={({ attribute }) => {
// Use different widgets based on attribute name
if (attribute === 'category') {
return <Menu attribute={attribute} />;
}
return <RefinementList attribute={attribute} />;
}}
>
<RefinementList attribute="brand" />
<Menu attribute="category" />
<RefinementList attribute="color" />
<RangeSlider attribute="price" />
</DynamicWidgets>
</InstantSearch>
);
}
How It Works
- The component fetches the list of facets from your Algolia index configuration
- It matches the facets with the widgets you provide as children (by
attribute or attributes prop)
- It renders only the widgets for facets that have values in the current search results
- If a facet has no matching widget, it uses the
fallbackComponent if provided
Index Configuration
For <DynamicWidgets> to work, your index must have attributesForFaceting configured:
{
"attributesForFaceting": [
"brand",
"color",
"category",
"size"
]
}
Notes
Only widgets with an attribute or attributes prop can be used inside <DynamicWidgets>. This includes <RefinementList>, <Menu>, <RangeSlider>, <ToggleRefinement>, etc.
The fallbackComponent prop must be a stable reference. Define it outside your component or use useCallback to avoid re-creating widgets on every render.
Dynamic Widgets are useful when you have multiple indices with different facets, or when you want to automatically adjust your UI based on the index configuration without code changes.