get Pagination Variablesutility
utility
Caution
This component is in an unstable pre-release state and may have breaking changes in a future release.
The function is used with the
<Pagination>
component to generate the variables needed to fetch paginated data from the Storefront API. The returned variables should be used within your storefront GraphQL query.
- Anchor to requestrequestRequestrequired
The request object passed to your Remix loader function.
- Anchor to optionsoptions{ pageBy: number; }Default: {pageBy: 20}
Options for how to configure the pagination variables. Includes the ability to change how many nodes are within each page.
GetPaginationVariablesGeneratedType
- request
The request object passed to your Remix loader function.
Request
- options
Options for how to configure the pagination variables. Includes the ability to change how many nodes are within each page.
{ pageBy: number; }
Variables to be used with the `storefront.query` function
export function getPaginationVariables(
request: Request,
options: {pageBy: number} = {pageBy: 20},
) {
if (typeof request?.url === 'undefined') {
throw new Error(
'getPaginationVariables must be called with the Request object passed to your loader function',
);
}
const {pageBy} = options;
const searchParams = new URLSearchParams(new URL(request.url).search);
const cursor = searchParams.get('cursor') ?? undefined;
const direction =
searchParams.get('direction') === 'previous' ? 'previous' : 'next';
const isPrevious = direction === 'previous';
const prevPage = {
last: pageBy,
startCursor: cursor ?? null,
};
const nextPage = {
first: pageBy,
endCursor: cursor ?? null,
};
const variables = isPrevious ? prevPage : nextPage;
return variables;
}
Was this section helpful?
Example code
import {json} from '@shopify/remix-oxygen';
import {Pagination, getPaginationVariables} from '@shopify/hydrogen';
import {useLoaderData, Link} from '@remix-run/react';
export async function loader({request, context: {storefront}}) {
const variables = getPaginationVariables(request, {pageBy: 8});
const data = await storefront.query(ALL_PRODUCTS_QUERY, {
variables,
});
return json({products: data.products});
}
export default function List() {
const {products} = useLoaderData();
return (
<Pagination connection={products}>
{({nodes, PreviousLink, NextLink}) => (
<>
<PreviousLink>Previous</PreviousLink>
<div>
{nodes.map((product) => (
<Link key={product.id} to={`/products/${product.handle}`}>
{product.title}
</Link>
))}
</div>
<NextLink>Next</NextLink>
</>
)}
</Pagination>
);
}
const ALL_PRODUCTS_QUERY = `#graphql
query AllProducts(
$country: CountryCode
$language: LanguageCode
$first: Int
$last: Int
$startCursor: String
$endCursor: String
) @inContext(country: $country, language: $language) {
products(first: $first, last: $last, before: $startCursor, after: $endCursor) {
nodes { id
title
handle
}
pageInfo {
hasPreviousPage
hasNextPage
startCursor
endCursor
}
}
}
`;
examples
Example code
description
I am the default example
JavaScript
import {json} from '@shopify/remix-oxygen'; import {Pagination, getPaginationVariables} from '@shopify/hydrogen'; import {useLoaderData, Link} from '@remix-run/react'; export async function loader({request, context: {storefront}}) { const variables = getPaginationVariables(request, {pageBy: 8}); const data = await storefront.query(ALL_PRODUCTS_QUERY, { variables, }); return json({products: data.products}); } export default function List() { const {products} = useLoaderData(); return ( <Pagination connection={products}> {({nodes, PreviousLink, NextLink}) => ( <> <PreviousLink>Previous</PreviousLink> <div> {nodes.map((product) => ( <Link key={product.id} to={`/products/${product.handle}`}> {product.title} </Link> ))} </div> <NextLink>Next</NextLink> </> )} </Pagination> ); } const ALL_PRODUCTS_QUERY = `#graphql query AllProducts( $country: CountryCode $language: LanguageCode $first: Int $last: Int $startCursor: String $endCursor: String ) @inContext(country: $country, language: $language) { products(first: $first, last: $last, before: $startCursor, after: $endCursor) { nodes { id title handle } pageInfo { hasPreviousPage hasNextPage startCursor endCursor } } } `;
TypeScript
import {json, type LoaderArgs} from '@shopify/remix-oxygen'; import {Pagination, getPaginationVariables} from '@shopify/hydrogen'; import {useLoaderData, Link} from '@remix-run/react'; import {ProductConnection} from '@shopify/hydrogen/storefront-api-types'; export async function loader({request, context: {storefront}}: LoaderArgs) { const variables = getPaginationVariables(request, {pageBy: 8}); const data = await storefront.query<{products: ProductConnection}>( ALL_PRODUCTS_QUERY, { variables, }, ); return json({products: data.products}); } export default function List() { const {products} = useLoaderData<typeof loader>(); return ( <Pagination connection={products}> {({nodes, NextLink, PreviousLink}) => ( <> <PreviousLink>Previous</PreviousLink> <div> {nodes.map((product) => ( <Link key={product.id} to={`/products/${product.handle}`}> {product.title} </Link> ))} </div> <NextLink>Next</NextLink> </> )} </Pagination> ); } const ALL_PRODUCTS_QUERY = `#graphql query AllProducts( $country: CountryCode $language: LanguageCode $first: Int $last: Int $startCursor: String $endCursor: String ) @inContext(country: $country, language: $language) { products(first: $first, last: $last, before: $startCursor, after: $endCursor) { nodes { id title handle } pageInfo { hasPreviousPage hasNextPage startCursor endCursor } } } `;