# Filters
# Introduction
Our filters feature allows you to fetch a product list based on selected options like color or size. These options are based on the product attributes added to the products on the page for each category.
# Retrieving filters
To build filtering in your application, first you need to retrieve filters from the BigCommerce API. To do that, you can use new useFetch composable.
The load
method of useFetch
composable will fetch filters from BigCommerce GraphQL API and return the raw response. The response from the GraphQL API is a little bit different than the response from BigCommerce REST API. For example, your response might look like this:
{
"edges": [
{
"node": {
"name": "Color",
"__typename": "ProductAttributeSearchFilter",
"attributes": {
"edges": [
{
"node": {
"value": "Black",
"productCount": 1,
"isSelected": false
}
},
{
"node": {
"value": "Blue",
"productCount": 1,
"isSelected": false
}
},
{
"node": {
"value": "Orange",
"productCount": 1,
"isSelected": false
}
},
{
"node": {
"value": "Silver",
"productCount": 1,
"isSelected": false
}
}
]
},
"isCollapsedByDefault": false
}
},
{
"node": {
"name": "Size",
"__typename": "ProductAttributeSearchFilter",
"attributes": {
"edges": [
{
"node": {
"value": "Large",
"productCount": 1,
"isSelected": false
}
},
{
"node": {
"value": "Medium",
"productCount": 1,
"isSelected": false
}
},
{
"node": {
"value": "Small",
"productCount": 1,
"isSelected": false
}
}
]
},
"isCollapsedByDefault": false
}
}
]
}
So to get the filter values, it's necessary to do some mapping to get each node. Based on this response, you can start building your UI for filters selection. Example implementation of fetching the filters might look like this:
setup() {
const { load, loading: filtersLoading } = useFilters();
const currentCategoryId = 1;
const filters = ref([]);
async function fetchAvailableFilters() {
const rawFilters = await load({
filters: {
categoryEntityId: currentCategoryId
}
});
return raw.edges.map((item) => item.node);
}
onMounted(() => {
filters.value = fetchAvailableFilters()
});
return filters;
}
# Filtering products
Filtering products by attributes is only available via the of BigCommerce GraphQL API. Our useProduct
example contains a method - filter
which can be used to get filtered product response.
To make this call properly, it's necessary to properly format the filter parameters.
For example, let's say we want to filter products in our current category to only get products where the Color
attribute equals Red
.
const exampleFilters = {
categoryEntityId: currentCategoryId,
productAttributes: [
{
attribute: 'Color',
values: ['Red']
}
]
};
The attribute
parameter should match as name
parameter of the filter response from Retrieving filters section. The values
parameter contains the array of attribute value
parameters in the same response.
If you want to filter by more attributes, you can add more attribute
/values
to the productAttributes
array.
const exampleFilters = {
categoryEntityId: currentCategoryId,
productAttributes: [
{
attribute: 'Color',
values: ['Red', 'Blue']
},
{
attribute: 'Size',
values: ['Large']
}
]
};
Example implementation of filtering products might look like this:
setup() {
const { filter } = useProduct();
const products = ref([]);
const pageInfo = ref({});
const sort = 'FEATURED';
const itemsPerPage = 10;
useFetch(async () => {
const filters = {
categoryEntityId: currentCategoryId,
productAttributes: [
{
attribute: 'Color',
values: ['Red', 'Blue']
},
{
attribute: 'Size',
values: ['Large']
}
]
}
const res = await filter({
filters,
first: itemsPerPage,
sort
});
products.value = res.data
pageInfo.value = res.meta
});
}
See UseProductInterface for more information about parameters and responses.
# Sorting
To use useProduct().filter
method with sorting, it's necessary to make some changes with Sort by
logic. BigCommerce GraphQL API requires other sorting values than REST API. Sorting values are added to themeConfig.js
file, below you can find configuration proper for GraphQL API and sorting:
productsSortOptions: [
{ label: 'Featured', id: 1, value: { sort: 'FEATURED' } },
{ label: 'Relevance', id: 2, value: { sort: 'RELEVANCE' } },
{ label: 'Best selling', id: 3, value: { sort: 'BEST_SELLING' } },
{ label: 'Best reviewed', id: 4, value: { sort: 'BEST_REVIEWED' } },
{ label: 'Newest', id: 5, value: { sort: 'NEWEST' } },
{ label: 'Name: A to Z', id: 6, value: { sort: 'A_TO_Z' } },
{ label: 'Name: Z to A', id: 7, value: { sort: 'Z_TO_A' } },
{
label: 'Price from high to low',
id: 8,
value: { sort: 'HIGHEST_PRICE' }
},
{ label: 'Price from low to high', id: 9, value: { sort: 'LOWEST_PRICE' } }
],
sort
params like FEATURED
or A_TO_Z
should be added as sort
param to useProduct().filter
method:
const { filter } = useProduct();
const res = await filter({
filters,
first: 10,
sort: 'FEATURED'
});
# Pagination
Default pagination does not exist in the BigCommerce integration so there is no way to create page functionality. However, there is a way to create Show more
logic on your website.
The idea is to fetch first part of the product at start, and add every new fetched product to the list of products instead of replacing it. First fetch might load 10 products, next fetch would add new 10 products to the list of products - now 20 products would be visible on the page.
To understand how to build such a feature, first you should focus on the response of useProduct().filter
method.
Example response might look like this:
{
"data": [
// List of products
],
"meta": {
"totalItems": 5,
"pageInfo": {
"hasNextPage": true,
"hasPreviousPage": false,
"startCursor": "WzEwMDAwMDAwMCwwLDkzXQ==",
"endCursor": "WzEwMDAwMDAwMCwwLDg4XQ=="
}
}
}
Information to build "show more" functionality is included in meta.pageInfo
param.
hasNextPage
defines if there are more products to fetchendCursor
is the unique value for each product that can be used to define after which product we want to start fetching more products
Then, we can use the filter
method and specify the after
parameter, where endCursor
should be used:
setup() {
const { filter } = useProduct();
const products = ref([]);
const pageInfo = ref({});
const sort = 'FEATURED';
const itemsPerPage = 10;
useFetch(async () => {
const filters = {
categoryEntityId: currentCategoryId,
productAttributes: [
{
attribute: 'Color',
values: ['Red', 'Blue']
},
{
attribute: 'Size',
values: ['Large']
}
]
}
const res = await filter({
filters,
first: itemsPerPage,
after: pageInfo.value.endCursor
sort
});
products.value = res.data
pageInfo.value = res.meta
});
}
Now, itemsPerPage
number of products will start fetching products after last where the previous fetch left off.
To create a feature that adds new product to previous list of products, useFetch
is a very helpful method to use. It returns { fetch }
function, that can use used to trigger its effect again.
WARNING
There is a bug in @nuxtjs/composition-api
package when useFetch
is used with computed
properties. It throws the error: [Vue warn]: Write operation failed: computed value is readonly.
. It does not break the functionality, but this error could be observed in the console. To avoid this error, there is a [workaround](https://github.com/nuxt-community/composition-api/issues/19.
Example implementation of filtering products with show more
functionality:
setup() {
const route = useRoute();
const { filter } = useProduct();
const filterProductsResponse = ssrRef({}, route.value.fullPath);
const products = ref([]);
const after = ref('');
const { fetch: refetchProducts } = useFetch(async () => {
const filters = prepareFilters();
const res = await filter({
filters,
after: after.value,
first: itemsPerPage,
sort
});
products.value = products.value.length
? [...products.value, ...res.data]
: res.data;
filterProductsResponse.value = res;
});
const { pagination, pageInfo } = usePagination(filterProductsResponse);
const showMore = () => {
if (pageInfo.value?.hasNextPage) {
after.value = pageInfo.value.endCursor;
refetchProducts();
}
};
return {
products,
showMore
}
}
# Limitations
Maximum 50 products can be fetched during 1 fetch - limitation of BigCommerce GraphQL API.