Navigation

Category listing with Search.js

Search.js can be used to render rich, interactive category listings. A category listing is a search, where the initial view is pre-filtered for a specific category and no user-typed query is present. This is similar to calling the Search API directly with a filter, like /search?f[]=category:T-shirts. In both cases, the request returns a list of all products from that category, sorted by the Luigi's Box system and respecting all of your configured merchandising rules.

The two-step process

A key aspect of using Search.js for product listings is understanding its two-step process:

  1. Initialization (Luigis.Search({...})): The first call you make is to Luigis.Search(). Its job is to initialize the entire search interface. It sets up all the components like facets and sorting and links the library to your HTML placeholders. At this stage, the UI is ready, but no search has been performed.
  2. Execution (Luigis.Search.Search(...)): The second call you make is to the Search() method on the already-initialized Luigis.Search object. Its job is to execute the initial search. For a listing page, you'll execute this with a null query but with a special IntentFilters object that tells the system what category to display.

Implementation details

There is almost nothing special about the main initialization call. Follow the same setup as when initializing a standard search page, including the loading placeholder for the best user experience.

The key to creating the category listing is the second call, which uses the IntentFilters configuration.

Luigis.Search.Search(
  null, // The query is null
  {
    ProductListingFilter: "category_id",
    IntentFilters: { category_id: 123 }
  }
);

Parameters:

  1. query (null): The search term users would type. Use null when displaying a category listing since you want to show all products in that category, not search results for specific keywords.

  2. configuration object with two key properties:

    • ProductListingFilter: This must match one of the keys used in IntentFilters. It tells Search.js which of the provided intent filters defines the current product listing context. The key can be any supported filter attribute. For category listings, special values like category_path and all_categories_path are often a good fit. For example, if you are filtering by label, nested_category_id, or category_path, you could use:
   ProductListingFilter: "label",
   IntentFilters: { label: "new" }

or:

   ProductListingFilter: "nested_category_id",
   IntentFilters: { nested_category_id: 23523 }
  • IntentFilters: Defines which filters to apply for the initial listing. These keys are part of the Search.js request setup and can use any supported search filter attributes.

Important

ProductListingFilter only needs to reference one of the keys present in IntentFilters. For category listings, prefer the attribute that best represents the page context, such as category_path or all_categories_path.

The IntentFilters are temporary and automatically clear when users start typing in the search box, seamlessly transitioning from browsing a category to searching across all products.

Complete example

Here is the full snippet showing the two-step process in action:

<script type="text/x-template" id="..">
</script>
<script type="text/x-template" id="..">
</script>

<script src="https://cdn.luigisbox.com/search.js"></script>
<script>
  // 1. First, INITIALIZE the search UI with all desired features and facets
Luigis.Search({
  TrackerId: 'YOUR_TRACKER_ID',
  Theme: 'boo',
  Facets: ['brand', 'price_amount'],
  DefaultFilters: {
     type: 'product' 
  }
}, '#search-input', '#search-ui');

// 2. Immediately after, EXECUTE a search for the category with id 123.
Luigis.Search.Search(
  null, // The query is null
  {
    ProductListingFilter: "category_id",
    IntentFilters: { category_id: 123 }
  }
);
</script>