Dynamic filters for data sources

👍

Prerequisites

The below articles should be read before starting this article:

The Frontastic schema language (which is used for Frontastic component schemas, data source schemas, and so on) allows you to define input forms for configuration in the Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`.. If the backend you attach Frontastic to supports a changing set of filters, it's challenging to keep up with your schema over time. To solve this, Frontastic supports the dynamic-filter field type.

A field of type dynamic-filter allows you to instruct the Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`. to load a schema definition from a given API endpoint. Instead of just rendering a static form, the Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`. will call the endpoint specified by the dynamic-filter field and present a list of filters to the user, which they can add.

A typical scenario for dynamic-filter is fetching searchable attributes from a backend system like an eCommerce product search, content search, or similar. Using a dynamic-filter, you can fetch the supported attributes directly from the backend and expose them to the Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`. as filter fields. In this scenario, you typically use dynamic-filter in the schema of a data source extension, but it's also possible to use it in any other schema.

dynamic-filter field in a schema

To use the power of dynamic filters, you need to add a field of this type to a schema. In this example, we're using a data source schema:

{
    "customDataSourceType": "example/star-wars-character",
    "name": "Star wars character",
    "category": "Content",
    "icon": "source",
    "schema": [
        {
            "name": "Character search",
            "fields": [
                {
                    "label": "Filters",
                    "field": "characterFilters",
                    "type": "dynamic-filter",
                    "dynamicFilterEndpoint": "/frontastic/action/star-wars/filters"
                }

            ]
        }
    ]
}

❗️

Before uploading your schema to the Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`., you need to deploy the action first to your production API hub instance. See the next section for how to do this.

The dynamic-filter field type carries an additional field attribute which references a URL on the API hub of the product. Since you can implement arbitrary API hub endpoints as part of an action extension, this extension type is used for implementing the actual fetching.

📘

You can identify the action extension by looking at the path mentioned in dynamicFiltersEndpoint. This one starts with /frontastic/action, which is the URL base path for such extensions. Find more in the developing an action extension article.

Implement the action to fetch the filters

export default {
    actions: {
        'star-wars': {
            filters: (request: Request, actionContext: ActionContext): Response => {
                return {
                    statusCode: '200',
                    body: JSON.stringify([
                        {
                            field: 'textSearch',
                            label: 'Text search',
                            type: 'text',
                            translatable: false,
                        },
                        {
                            field: 'lightSideOnly',
                            label: 'Only light side?',
                            type: 'boolean',
                        },
                    ]),
                };
            },
        },
    }
};

Action registration works as with every action through the index.ts export. In this example, the action code doesn't fetch dynamic attributes from a backend but instead returns static JSON defining 2 fields (textSearch and lightSaberOnly).

The action can return any filter fields of any Frontastic schemas including (for example) enum or translatable fields. You need to ensure that each field name is unique within a single dynamic filter set.

🚧

A dynamic-filter action underlies the usual timeout constraints of Frontastic studio and should so not take more than 100ms to run. In addition, it's important not to flood Frontastic studio with a huge number of fields or enum-values. We recommend no more than 30 fields overall and 20 values for an enum.

Test dynamic filters in Frontastic studio

To test the dynamic filters in the Frontastic studio, you need to upload the created data source schema and create a data source configuration on a page folder. Then you'll be able to add filters dynamically like in the below gif:

Configuration received from dynamic filters

In the data source implementation, you'll receive the configured dynamic filters in the following format:

{
  "streamId": "515869c1-d45d-4ef5-b213-5c48879a43c8",
  "type": "example/star-wars-character",
  "name": "Star wars character",
  "configuration": {
    "characterFilters": {
      "filters": [
        {
          "field": "textSearch",
          "type": "text"
        },
        {
          "field": "lightSideOnly",
          "type": "boolean"
        }
      ],
      "values": {
        "textSearch": "luke",
        "lightSideOnly": true
      }
    }
  }
}

The characterFilters field (which is of type dynamic-filter contains a hashmap of values that reflects the actual values entered by the user in the Frontastic studio. It also contains a stripped-down list of the filter definitions used to provide you:
a) with the correct order of the filters
b) with the types you assigned the filters

Both might be relevant for translating them back into queries towards your backend system.


Did this page help you?