Being new to Sitecore headless with NextJs is overwhelming for anyone but at the same time can be a pain for beginners who don’t find directions or articles when searching on a topic on which they are stuck. So I thought I will share this post on how to implement pagination from the front end side as I do not see any article about it.
This blog post will show you how you can build pagination with your Nextjs App using GraphQL.
Background
Paginated queries and fields within the Experience Edge schema, like a Product listing query, Search query utilize a cursor-based system to request result pages. Below are some terms which we will focus on to achieve pagination.
- first: Any Query will include the first argument, if you do not pass it by default it would be 10. This specifies the number of results to return from query execution.
- pageInfo: Executed query results include this property nested with hasNext ( specifies whether after current execution more results are available) and endCursor ( specifies reference point that must be passed in the next GraphQL request to get more results).
- total: provides the total number of available results for the query provided irrespective of whether all results are part of the results response or not.
- after: This query argument would be used to pass ‘endCursor‘ value for subsequent requests to get more results or in other words paginated results
The first argument has a special meaning to query the complexity calculation used by the underlying GraphQL library of the Preview schema. Using the nested children field on the Item graph type, in particular, can quickly lead to Query is too complex to execute errors. To work around this, you can increase the maxComplexity value of the complexityConfiguration setting. See Sitecore GraphQL documentation and GraphQL .NET documentation for more information.
Implementation
Out of the box, you wouldn’t have pagination built in for GraphQL Request but rather we can build in logic to support it. Let’s imagine we have to list product items from Sitecore and due to the complexity of the query and not more room for filters to return more results we could achieve just 50 products. The number of products in Sitecore can grow more than that, hence in this case we can create a helper class and all it does is loop through results and push it to an array and then return the array of results.
/**
* Aggregates pagination results into a single result-set.
*/
export const getAllItems = async <T>(
graphqlQuery: string,
args: SearchQueryVariables
): Promise<T[]> => {
let returnItems: T[] = [];
let shouldQueryMoreItems = true;
let after = '';
while (shouldQueryMoreItems) {
const fetchResponse = await graphqlClient.request<GraphqlSearchResponse<T>>(graphqlQuery, {
...args,
after,
});
returnItems = returnItems.concat(fetchResponse?.search?.results);
shouldQueryMoreItems = fetchResponse.search.pageInfo.hasNext;
after = fetchResponse.search.pageInfo.endCursor;
}
return returnItems;
};
In the above code, all we do is first default shouldQueryMoreItems =True and after = ”, then in the While loop we just repeatedly call the GraphQL endpoint, push returned results into our results variable , assign the endCursor to the after, and hasNext to our shouldQueryMoreItems . ( Go to section above to view more details)
Once you have that all you need to do is call the above method from your component static props method to get all results in one go.
const result = await getAllItems<SearchResponse>(query, queryVariables);
Hope this helps someone who is looking for it. Happy Next Sitecoring 😉