1. Search experiences

Facets

Version:

Using facets is a common way to reduce the number of search results, so the site visitor can find the content they're interested in faster. A search facet is for further refining the search results that are already returned to your app. Facets are displayed in the user interface, typically on the search results page, and site visitors use them to narrow down the search results.

For example, site visitors can apply facets on an e-commerce site to refine search results by clothing size, price, color, or brand; or on a content-driven site to refine them by product or by document types such as video, audio, or PDF.

Every entity can be configured with one or more facets in Sitecore Search > Administration > Domain Settings > Feature Configuration > Facets. When you request facet data using the Cloud SDK, you can use the FacetOptions interface to request all facet types that are configured for an entity, or only those that you specify.

Requesting all or some facets

Consider a Location entity that describes all your organization's offices around the world. This entity is configured with two facets: region and office_type. When you request index documents for this entity, you can request all the available facets by setting facet.all to true:

import { Context, getWidgetData, SearchWidgetItem, WidgetRequestData } from "@sitecore-cloudsdk/search/browser";

// ...

// Depending on your Sitecore Search configuration, using `Context` might be optional:
const context = new Context({});
context.locale = {
  language: "en",
  country: "us"
};

// Create a new widget request:
const widgetRequest = new SearchWidgetItem("location", "rfkid_7", {
  content: {},
  limit: 10,
  facet: { all: true } // Request all available facets
});

const response = await getWidgetData(new WidgetRequestData([widgetRequest]), context);

The response will contain all available facets, returned in widgets.facet:

{
  "widgets": [
    {
      "rfk_id": "rfkid_7",
      "type": "content_grid",
      "used_in": "page",
      "entity": "location",
      "facet": [
        {
          "name": "Region",
          "label": "Region",
          "value": [ ... ]
        },
        {
          "name": "office_type",
          "label": "Office Type",
          "value": [ ... ]
        }
      ],
      "content": [ ... ],
      "total_item": 1,
      "limit": 1,
      "offset": 0
    }
  ],
  "dt": 24,
  "ts": 1737392782884
}

Alternatively, you can request only certain facets by setting facet.types to an array of facet names:

// ...
const widgetRequest = new SearchWidgetItem("location", "rfkid_7", {
  content: {},
  limit: 10,
  // facet: { all: true } // Request all available facets
  facet: { types: [{ name: "region" }] } // Request the "region" facet only
});

The response will contain facet data only for the facets you specified, returned in widgets.facet:

{
  "widgets": [
    {
      "rfk_id": "rfkid_7",
      "type": "content_grid",
      "used_in": "page",
      "entity": "location",
      "facet": [
        {
          "name": "Region",
          "label": "Region",
          "value": [ ... ]
        }
      ],
      "content": [ ... ],
      "total_item": 1,
      "limit": 1,
      "offset": 0
    }
  ],
  "dt": 24,
  "ts": 1737392782884
}

Elements of a facet

Facets consist of multiple elements. Each element is important for your development work, but you'll typically only show some of the elements in the user interface.

Consider the following facet interface on the developers.sitecore.com search results page:

Elements of a facet in the developers.sitecore.com user interface

This user interface contains three facet blocks. Each block has:

XM Cloud is now SitecoreAI

Some code examples, images, and UI labels may still use XM Cloud while engineering assets are being updated.

  • A facet title (Site name, Product, Type).

  • Various facet values. Each facet value has:

    • A facet label (such as Sitecore Documentation, GitHub, Changelog, or Repository), visible in the user interface.

    • A facet ID, such as "id-12345", not visible in the user interface.

    • The number of results that match with the facet value, visible in the user interface.

The corresponding response contains each facet element, returned in widgets.facet:

{
  "widgets": [
    {
      ...
      "facet": [
        // facet block for "Site name"
        {
          "name": "site_name",
          "label": "Site name", // facet title
          "value": [ // facet value
            {
              "id": "id-12345", // facet ID
              "text": "Sitecore Documentation", // facet label
              "count": 4487 // number of results
            }
          ]
        }
      ]
    }
  ]
}

Filtering search results by facet values

When the site visitor selects one or more facet values, the list of search results is refreshed to only show results that match those values. To enable this, you apply filters to request search content that matches the selected facet values.

You can use the facet.types.filter attribute of the FacetOptions interface to apply filters to facet values. In facet.types.filter.values, you specify the facet values you want to include in the filter.

You can specify facet values either by the facet label (Sitecore Documentation) or the facet ID ("id-12345"). Filtering by facet ID is more performant than filtering by facet labels.

Example 24. Filter search results by a single facet

Consider a scenario where the site visitor selects a single facet value to narrow down search results.

Here's an example of using the facet label Europe in facet.types.filter.values to list offices in the Europe region:

import {
  ComparisonFacetFilter,
  Context,
  getWidgetData,
  SearchWidgetItem,
  widgetItemClick,
  WidgetRequestData
} from "@sitecore-cloudsdk/search/browser";

const context = new Context({});
context.locale = {
  language: "en",
  country: "us"
};

const widgetRequest = new SearchWidgetItem("location", "rfkid_7", {
  content: {},
  limit: 10,
  facet: {
    all: true,
    // Filter by facet label "Europe":
    types: [
      {
        name: "region",
        filter: {
          type: "or",
          values: [new ComparisonFacetFilter("eq", "Europe")]
        }
      }
    ]
  }
});

const response = await getWidgetData(new WidgetRequestData([widgetRequest]), context);

Alternatively, instead of the facet label, you can use the facet ID that corresponds with the Europe facet value, such as "id-12345":

// ...
const searchWidget = new SearchWidgetItem("location", "rfkid_7", {
    // ...
    // Filter by facet ID "id-12345":
    types: [{
            name: "region",
            filter: {
                type: "or",
                values: ["id-12345"]
            }
        }]
    }
});

Regardless of whether you use the facet label or the facet ID, the response will only contain index documents that match the Europe region, returned in widgets.content:

{
  "widgets": [
    {
      "rfk_id": "rfkid_7",
      "type": "content_grid",
      "used_in": "page",
      "entity": "location",
      "facet": [
        {
          "name": "region",
          "label": "Region",
          "value": [ ... ]
        },
        {
          "name": "office_type",
          "label": "Office Type",
          "value": [ ... ]
        }
      ],
      "content": [
        {
          ...
          "region": "Europe",
          ...
        },
        {
          ...
          "region": "Europe",
          ...
        },
        {
          ...
          "region": "Europe",
          ...
        },
        { ... }
      ],
      "total_item": 14,
      "limit": 5,
      "offset": 0
    }
  ],
  "dt": 47,
  "ts": 1737394846427
}


Example 25. Filter search results by multiple facets

Consider a scenario where the site visitor selects multiple facet values to narrow down search results.

Here's an example of using multiple facet labels in facet.types.filter.values to list offices in multiple regions:

types: [
  {
    name: "region",
    filter: {
      type: "or",
      values: [new ComparisonFacetFilter("eq", "Europe"), new ComparisonFacetFilter("eq", "North America")]
    }
  }
];

Alternatively, instead of the facet labels, you can use the facet IDs that correspond with the facet values:

types: [
  {
    name: "region",
    filter: {
      type: "or",
      values: ["id-12345", "id-67890"]
    }
  }
];

Regardless of whether you use facet labels or facet IDs, the response will only contain index documents that match one of the specified regions, returned in widgets.content:

{
  "widgets": [
    {
      "rfk_id": "rfkid_7",
      "type": "content_grid",
      "used_in": "page",
      "entity": "location",
      "facet": [
        {
          "name": "region",
          "label": "Region",
          "value": [ ... ]
        },
        {
          "name": "office_type",
          "label": "Office Type",
          "value": [ ... ]
        }
      ],
      "content": [
        {
          ...
          "region": "Europe",
          ...
        },
        {
          ...
          "region": "North America",
          ...
        },
        {
          ...
          "region": "North America",
          ...
        },
        { ... }
      ],
      "total_item": 21,
      "limit": 5,
      "offset": 0
    }
  ],
  "dt": 47,
  "ts": 1737394846427
}


If you have suggestions for improving this article, let us know!