Skip to main content
Signature
dynamicWidgets({
  container: string | HTMLElement,
  widgets: function[],
  // Optional parameters
  transformItems?: function,
  fallbackWidget?: function,
  facets?: ['*']|[],
  maxValuesPerFacet?: number,
});

Import

import { dynamicWidgets } from "instantsearch.js/es/widgets";

About this widget

dynamicWidgets is a widget that displays matching widgets, based on the corresponding index settings and applied index rules. You can configure the facet merchandising through the corresponding index setting. To learn more, see Facet display.

Requirements

You must set the attributes for faceting and configure the facet order, either using the dashboard or with the API parameters attributesForFaceting and renderingContent. All matching widgets mount after the first network request completes. To avoid a second network request, facets are set to ['*'] and maxValuesPerFacet is set to 20 by default. You can override these settings with the facets and maxValuesPerFacet parameters.
You must use InstantSearch.js v4.72.0 or later to use dynamicWidgets.

Examples

dynamicWidgets({
  container: "#dynamic-widgets",
  widgets: [
    (container) => refinementList({ container, attribute: "brand" }),
    (container) =>
      hierarchicalMenu({
        container,
        attributes: [
          "hierarchicalCategories.lvl0",
          "hierarchicalCategories.lvl1",
        ],
      }),
  ],
  fallbackWidget: ({ container, attribute }) =>
    panel({ templates: { header: attribute } })(menu)({ container, attribute }),
});

Options

container
string | HTMLElement
required
The CSS Selector of the DOM element inside which the widget is inserted.
dynamicWidgets({
  // ...
  container: "#dynamic-widgets",
});
widgets
Array<(container: HTMLElement) => Widget>
required
A list of creator functions for all refinement widgets you want to conditionally display. Each creator will receive a container and is expected to return a widget. The creator can also return custom widgets created with connectors.Note that the returned widget needs to have an “attribute” or “attributes” argument, as this will be used to determine which widgets to render in which order.
dynamicWidgets({
  // ...
  widgets: [(container) => refinementList({ container, attribute: "brand" })],
});
fallbackWidget
(args: { attribute: string, container: HTMLElement }) => Widget
A creator function that is called for every attribute you want to conditionally display. The creator will receive a container and attribute and is expected to return a widget. The creator can also return custom widgets created with connectors.
dynamicWidgets({
  // ...
  fallbackWidget: ({ container, attribute }) =>
    refinementList({ container, attribute }),
});
transformItems
function
A function to transform the attributes to render, or using a different source to determine the attributes to render.
JavaScript
dynamicWidgets({
  // ...
  transformItems(items, { results }) {
    return items;
  },
});
facets
['*']|[]
default:"['*']"
The facets to apply before dynamic widgets get mounted. Setting the value to ['*'] will request all facets and avoid an additional network request once the widgets are added.
dynamicWidgets({
  // ...
  facets: ["*"],
});
maxValuesPerFacet
number
default:20
The default number of facet values to request. It’s recommended to have this value at least as high as the highest limit and showMoreLimit of dynamic widgets, as this will prevent a second network request once that widget mounts.To avoid pinned items not showing in the result, make sure you choose a maxValuesPerFacet at least as high as all the most pinned items you have.
JavaScript
dynamicWidgets({
  // ...
  maxValuesPerFacet: 500,
});

Customize the UI with connectDynamicWidgets

If you want to create your own UI of the dynamicWidgets widget, you can use connectors. To use connectDynamicWidgets, you can import it with the declaration relevant to how you installed InstantSearch.js.
import { connectDynamicWidgets } from "instantsearch.js/es/connectors";
Then it’s a 3-step process:
JavaScript
// 1. Create a render function
const renderDynamicWidgets = (renderOptions, isFirstRender) => {
  // Rendering logic
};

// 2. Create the custom widget
const customDynamicWidgets = connectDynamicWidgets(renderDynamicWidgets);

// 3. Instantiate
search.addWidgets([
  customDynamicWidgets({
    // instance params
  }),
]);

Create a render function

This rendering function is called before the first search (init lifecycle step) and each time results come back from Algolia (render lifecycle step).
JavaScript
const renderDynamicWidgets = (renderOptions, isFirstRender) => {
  const { attributesToRender, widgetParams } = renderOptions;

  if (isFirstRender) {
    // Do some initial rendering and bind events
  }

  // Render the widget
};

Rendering options

attributesToRender
string[]
The list of refinement values to display returned from the Algolia API.
JavaScript
const renderDynamicWidgets = (renderOptions, isFirstRender) => {
  const { attributesToRender } = renderOptions;

  document.querySelector("#dynamic-widgets").innerHTML = `
    <ul>
      ${attributesToRender
        .map(
          (attribute) => `
            <li>
              ${attribute}
            </li>`,
        )
        .join("")}
    </ul>
  `;
};
widgetParams
object
All original widget options forwarded to the render function.
JavaScript
const renderDynamicWidgets = (renderOptions, isFirstRender) => {
  const { widgetParams } = renderOptions;

  widgetParams.container.innerHTML = "...";
};

// ...

search.addWidgets([
  customDynamicWidgets({
    // ...
    container: document.querySelector("#dynamic-widgets"),
  }),
]);

Create and instantiate the custom widget

First, create your custom widgets using a rendering function. Then, instantiate them with parameters. There are two kinds of parameters you can pass:
  • Instance parameters. Predefined options that configure Algolia’s behavior.
  • Custom parameters. Parameters you define to make the widget reusable and adaptable.
Inside the renderFunction, both instance and custom parameters are accessible through connector.widgetParams.
JavaScript
const customDynamicWidgets = connectDynamicWidgets(
  renderDynamicWidgets
);

search.addWidgets([
  customDynamicWidgets({
    widgets: object[],
    // Optional parameters
    transformItems?: function,
    facets?: string[],
    maxValuesPerFacet?: number,
  })
]);

Instance options

widgets
object[]
required
The widgets to dynamically add to the parent index. You manually need to update their DOM position.
JavaScript
customDynamicWidgets({
  widgets: [
    refinementList({
      // ...
    }),
    customWidget({
      // ...
    }),
  ],
});
transformItems
function
A function to transform the attributes to render, or using a different source to determine the attributes to render.
JavaScript
customDynamicWidgets({
  // ...
  transformItems(items, { results }) {
    return items;
  },
});
facets
['*']|[]
default:"['*']"
The facets to apply before dynamic widgets get mounted. Setting the value to ['*'] will request all facets and avoid an additional network request once the widgets are added.
customDynamicWidgets({
  // ...
  facets: ["*"],
});
maxValuesPerFacet
number
default:20
The default number of facet values to request. It’s recommended to have this value at least as high as the highest limit and showMoreLimit of dynamic widgets, as this will prevent a second network request once that widget mounts.To avoid pinned items not showing in the result, make sure you choose a maxValuesPerFacet at least as high as all the most pinned items you have.
JavaScript
customDynamicWidgets({
  // ...
  maxValuesPerFacet: 500,
});

Full example

<div id="dynamic-widgets"></div>
I