API Reference / React InstantSearch Widgets / DynamicWidgets
Widget signature
<ExperimentalDynamicWidgets
  // optional parameters
  transformItems={function}
  fallbackComponent={Element}
>
  {children}
</ExperimentalDynamicWidgets>

About this widget

DynamicWidgets is a widget that displays matching widgets, based on by the corresponding settings of the index and may be altered by a query rule. You can configure the facet merchandising through the corresponding index setting.

Requirements

Examples

1
2
3
4
5
6
7
<ExperimentalDynamicWidgets fallbackComponent={Menu}>
  <RefinementList attribute="brand" />
  <HierarchicalMenu attributes={["hierarchical.lvl0", "hierarchical.lvl1"]} />
  <Panel>
    <Menu attribute="category" />
  </Panel>
</ExperimentalDynamicWidgets>

Options

children
type: Element[]
Optional

The children of this component will be displayed dynamically based on the result of facetOrdering. This means that any child needs to have either the “attribute” or “attributes” prop.

1
2
3
<ExperimentalDynamicWidgets>
  <RefinementList attribute="brand" />
</ExperimentalDynamicWidgets>
fallbackComponent
type: Widget
Optional

The fallbackComponent prop is used if no widget from children matches. The component gets called with an attribute prop.

1
<ExperimentalDynamicWidgets fallbackComponent={RefinementList} />
transformItems
type: function
Optional

A function to transform the attributes to render, or using a different source to determine the attributes to render.

1
2
3
4
5
<ExperimentalDynamicWidgets
  transformItems={(items, { results }) => {
    return items;
  }},
/>

Customize the UI - EXPERIMENTAL_connectDynamicWidgets

If you want to create your own UI of the DynamicWidgets widget or use another UI library, you can use connectors.

Connectors are higher-order components. They encapsulate the logic for a specific kind of widget and they provide a way to interact with the InstantSearch context.

They have an outer component API that we call exposed props, and they provide some other props to the wrapped components which are called the provided props.

It’s a 3-step process:

// 1. Create a React component
const DynamicWidgets = () => {
  // return the DOM output
};

// 2. Connect the component using the connector
const CustomDynamicWidgets = EXPERIMENTAL_connectDynamicWidgets(DynamicWidgets);

// 3. Use your connected widget
<CustomDynamicWidgets />

Create a React component

const DynamicWidgets = ({
  object[] attributesToRender,
}) => {
  // return the DOM output
};

Provided Props

Rendering options

attributesToRender
type: string[]

The list of refinement values to display returned from the Algolia API.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function DynamicWidgets({
  attributesToRender,
}) {

  // on initial render this will be empty, but React InstantSearch keeps
  // search state for unmounted components in place, so routing works.
  return (
    <>
      {attributesToRender.map(attribute => (
        <RefinementList key={attribute} attribute={attribute} />
      ))}
    </>
  );
}

Create and instantiate your connected widget

const CustomDynamicWidgets = connectDynamicWidgets(DynamicWidgets);

<CustomDynamicWidgets
  // optional parameters
  transformItems={function}
/>

Exposed Props

Instance options

transformItems
type: function
Optional

A function to transform the attributes to render, or using a different source to determine the attributes to render.

1
2
3
4
5
<CustomDynamicWidgets
  transformItems={(items, { results }) => {
    return items;
  }}
/>

Full example

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// 0. Create a function to extract the attribute from a widget
function getAttribute(component) {
  if (typeof component !== 'object') {
    return undefined;
  }

  if (component.props.attribute) {
    return component.props.attribute;
  }
  if (Array.isArray(component.props.attributes)) {
    return component.props.attributes[0];
  }
  if (component.props.children) {
    return getAttribute(React.Children.only(component.props.children));
  }

  return undefined;
}

// 1. Create a render function
const RenderDynamicWidgets = ({
  attributesToRender,
  fallbackComponent: Fallback,
  children,
}) => {
  const widgets = new Map();

  // retrieve the attribute for children
  React.Children.forEach(children, (child) => {
    const attribute = getAttribute(child);
    if (!attribute) {
      throw new Error(
        `Could not find "attribute" prop for ${getDisplayName(child)}.`
      );
    }
    widgets.set(attribute, child);
  });

  // on initial render this will be empty, but React InstantSearch keeps
  // search state for unmounted components in place, so routing works.
  return (
    <>
      {attributesToRender.map((attribute) => (
        <Fragment key={attribute}>
          {widgets.get(attribute) || <Fallback attribute={attribute} />}
        </Fragment>
      ))}
    </>
  );
};

// 2. Create the custom widget
const CustomDynamicWidgets = EXPERIMENTAL_connectDynamicWidgets(
  RenderDynamicWidgets
);

// 3. Instantiate
<CustomDynamicWidgets fallbackComponent={Menu}>
  <Panel>
    <RefinementList attribute="brand" />
  </Panel>
</CustomDynamicWidgets>;

Did you find this page helpful?