---
title: Category listing with Search.js
description: Use Search.js to render rich, interactive category listings as product listing pages.
slug: product-listing/search-js
docKind: guide
hub: product-listing
---

[Search.js](/search/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`.

## The two-step process

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

1. **Initialization (`Luigis.Search({...})`)**: Sets up the entire search interface -- all components like facets and sorting -- and links the library to your HTML placeholders. No search is performed yet.
2. **Execution (`Luigis.Search.Search(...)`)**: Executes the initial search. For a listing page, you execute this with a `null` query but with a special `IntentFilters` object that tells the system what category to display.

## Implementation details

Follow the same setup as when initializing a standard search page, including the [loading placeholder](/search/search-js/) for the best user experience.

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

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

**Parameters:**

1. **query** (`null`): 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`**: Must match one of the keys used in `IntentFilters`. Tells Search.js which filter defines the current product listing context.
   - **`IntentFilters`**: Defines which filters to apply for the initial listing.

:::caution
`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

```html
<script src="https://cdn.luigisbox.com/search.js"></script>
<script>
  // 1. First, INITIALIZE the search UI
  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 category id 123
  Luigis.Search.Search(
    null,
    {
      ProductListingFilter: "category_id",
      IntentFilters: { category_id: 123 }
    }
  );
</script>
```
