docs/docs/guides/core-concepts/collections/index.mdx
Collections are used to categorize and organize your catalog. A collection
contains multiple product variants, and a product variant can belong to multiple collections. Collections can be nested to
create a hierarchy of categories, which is typically used to create a menu structure in the storefront.
Collections are not only used as the basis of storefront navigation. They are a general-purpose organization tool which can be used for many purposes, such as:
The specific product variants that belong to a collection are determined by the collection's CollectionFilters.
A collection filter is a piece of logic which is used to determine whether a product variant should be included in the collection. By default, Vendure
includes a number of collection filters:
Collections often work hand-in-hand with facets and filters to provide structured navigation in your storefront.
When a collection is nested within another collection, the child collection can inherit the parent's collection filters. This means that the child collection will combine its own filters with the parent's filters.
In the example above, we have a parent collection "Menswear", with a child collection "Mens' Casual". The parent collection has a filter which includes all product variants with the "clothing" and "mens" facet values. The child collection is set to inherit the parent's filters, and has an additional filter which includes all product variants with the "casual" facet value.
Thus, the child collection will include all product variants which have the "clothing", "mens" and "casual" facet values.
:::note When filter inheritance is enabled, a child collection will contain a subset of the product variants of its parent collection.
In order to create a child collection which contains product variants not contained by the parent collection, you must disable filter inheritance in the child collection. :::
For details on creating custom collection filters, see the Developer Guide.
You can create your own custom collection filters with the CollectionFilter class. This class
is a configurable operation where the specific
filtering logic is implemented in the apply() method passed to its constructor.
The apply() method receives an instance of the TypeORM SelectQueryBuilder which should have filtering logic
added to it using the .andWhere() method.
Here's an example of a collection filter which filters by SKU:
import { CollectionFilter, LanguageCode } from '@vendure/core';
export const skuCollectionFilter = new CollectionFilter({
args: {
// The `args` object defines the user-configurable arguments
// which will get passed to the filter's `apply()` function.
sku: {
type: 'string',
label: [{ languageCode: LanguageCode.en, value: 'SKU' }],
description: [
{
languageCode: LanguageCode.en,
value: 'Matches any product variants with an SKU containing this value',
},
],
},
},
code: 'variant-sku-filter',
description: [{ languageCode: LanguageCode.en, value: 'Filter by matching SKU' }],
// This is the function that defines the logic of the filter.
apply: (qb, args) => {
// Sometimes syntax differs between database types, so we use
// the `type` property of the connection options to determine
// which syntax to use.
const LIKE = qb.connection.options.type === 'postgres' ? 'ILIKE' : 'LIKE';
return qb.andWhere(`productVariant.sku ${LIKE} :sku`, {
sku: `%${args.sku}%`
});
},
});
In the apply() method, the product variant entity is aliased as 'productVariant'.
This custom filter is then added to the defaults in your config:
import { defaultCollectionFilters, VendureConfig } from '@vendure/core';
import { skuCollectionFilter } from './config/sku-collection-filter';
export const config: VendureConfig = {
// ...
catalogOptions: {
collectionFilters: [
...defaultCollectionFilters,
skuCollectionFilter // [!code highlight]
],
},
};
:::info To see some more advanced collection filter examples, you can look at the source code of the default collection filters. :::