Shopify Custom and Default Filters

Most storefront filters should be configured in Filters & Data and Layout Settings. Use JavaScript custom and default filters only for behavior that cannot be represented as a normal merchant-managed facet.

These hooks must be defined before the Search Results or Product Grid App Block starts.


Default Filters

Use window.Nimstrata.search.defaultFilters for hidden filters that should apply to every search or collection request.

Default filters are not shown in the UI, are not shopper-removable, and are not reflected as normal filter controls. They are a good fit for:

  • Store, warehouse, or region availability gates
  • B2B buyer segmentation
  • Channel-specific product restrictions
  • Temporary launch constraints that should not appear as shopper filters
window.Nimstrata = window.Nimstrata || {};
window.Nimstrata.search = window.Nimstrata.search || {};

window.Nimstrata.search.defaultFilters = [
  {
    field: 'attributes.available_in_market',
    value: ['GB'],
    type: 'string',
  },
  {
    or: [
      { field: 'attributes.channel', value: ['online'], type: 'string' },
      { field: 'attributes.channel', value: ['both'], type: 'string' },
    ],
  },
];

defaultFilters can also be a sync or async function:

window.Nimstrata.search.defaultFilters = async function () {
  const profile = await window.getCustomerProfile?.();

  return profile?.b2b
    ? [{ field: 'attributes.customer_group', value: ['b2b'], type: 'string' }]
    : [];
};

Collection pages already add their collection constraints through the App Block. Only add a collection ID, tag, or market filter manually during a manual install or when intentionally applying an extra hidden rule.


Custom Filters

Use window.Nimstrata.search.customFilters when shoppers need a visible switch for a filter that is not part of the normal facet list.

The current storefront UI supports displayComponent: 'switch'. Custom switches can render in the toolbar or in the sidebar/filter drawer.

window.Nimstrata = window.Nimstrata || {};
window.Nimstrata.search = window.Nimstrata.search || {};
window.Nimstrata.search.customFilters =
  window.Nimstrata.search.customFilters || [];

window.Nimstrata.search.customFilters.push({
  name: 'in_stock',
  displayName: 'In stock',
  displayComponent: 'switch',
  displayLocation: 'toolbar',
  defaultActive: false,
  filter: {
    field: 'availability',
    value: ['IN_STOCK'],
    type: 'string',
  },
});

Use the nested filter property for new work. Older inline custom filters with field, value, and type still work for backwards compatibility.

The beta conversational agent stock policy also resolves a custom filter by name in the storefront browser. If the agent setting uses source: "auto" and customFilterName: "in_stock", chat searches use the resolved in_stock filter and product-discovery turns can enable that same visible switch when applyToVisibleSearch is on. This is intended for profile-aware filters that cannot be stored statically in app metadata.


Custom Filter Fields

The search App Block only receives facet metadata for fields that are requested as filters. If a custom filter uses a field that is not already in the App Block filter list, add it to window.Nimstrata.search.customFields so the storefront can decide whether the switch is relevant for the current result set.

window.Nimstrata.search.customFields = [
  { field: 'attributes.available_in_store', type: 'number' },
];

Without this, a custom switch may be hidden because the storefront cannot confirm that applying it could return results.


Conditional Filter Visibility

Use window.Nimstrata.search.filterVisibilityRules when a normal App Block filter should render only under a bespoke storefront condition.

Each rule targets one normal facet with field and provides a pure visibleWhen callback. The callback can inspect current facet metadata, active shopper filters, and helper functions such as getFacetValues(field) and getFilterValues(field). A returned true keeps the facet visible, including when the default auto-hide rule would otherwise hide it. A returned false hides the facet from the drawer and quick filters.

When a hidden field has active shopper-selected values, the App Block removes those values by default so hidden filters do not continue narrowing results. Set clearWhenHidden: false only when a hidden active filter should intentionally keep affecting the request.

Keep every field used by the rule in the App Block filter list. For example, a rule that checks brands must still request the brands facet, even if the storefront's existing auto-hide behavior hides the brand filter when only one brand is available.

window.Nimstrata = window.Nimstrata || {};
window.Nimstrata.search = window.Nimstrata.search || {};

window.Nimstrata.search.filterVisibilityRules = [
  {
    field: 'attributes.series',
    visibleWhen: ({ getFacetValues, getFilterValues }) => {
      const selectedBrands = getFilterValues('brands');

      if (selectedBrands.length > 0) {
        return selectedBrands.length === 1;
      }

      return getFacetValues('brands').length === 1;
    },
  },
];

This example is useful for a storefront such as Wardow, where attributes.series should appear only after the result set is narrowed to one brand. If a collection page has only one available brand, brands may be auto-hidden while attributes.series still renders. If a shopper selects two brands, attributes.series is hidden again and any selected series values are cleared.


Default Active Custom Filters

Set defaultActive: true when a custom filter should start enabled but still be shopper-removable.

The URL uses cf for custom filters the shopper turns on and cf-off for default-active custom filters the shopper turns off. Use the name as the stable identifier, and avoid changing it once URLs are live.


Search Versus Recommendations

Search and collection pages use window.Nimstrata.search.defaultFilters.

Recommendations use a separate property:

window.Nimstrata = window.Nimstrata || {};
window.Nimstrata.recs = window.Nimstrata.recs || {};
window.Nimstrata.recs.defaultFilters = [
  { field: 'attributes.available_in_market', value: ['GB'], type: 'string' },
];

Recommendations automatically include an in-stock filter unless the configured recommendation filters already include an availability filter, including one nested inside or, and, or not.


When Not To Use These Hooks

Do not use custom or default filters to replace normal filter configuration. If the filter should appear as a normal facet, configure the attribute in App Block Filters. If the filter is only about layout, count display, quick filters, search-within-filters, or sorting placement, use Layout Settings.