Build product listing pages (Shopify Hydrogen)

This is for:

Developer

Building product listing pages (PLPs) with Coveo Headless involves three main elements:

  1. Keeping the URL up to date with the Headless state as you navigate between pages by using a hook on the ParameterManager controller.

  2. Fetching and displaying listing results by using a hook on the ProductList controller.

  3. Wrapping your components with a listing provider so that you can manage the Headless listing state and hydration.

Prerequisite

Make sure that you understand how to build product listing pages (PLPs).

Keep the URL up to date

Keep the URL state updated in Headless to ensure that the correct product listing page (PLP) is fetched when navigating between pages.

The loader uses fetchStaticState to sync the URL state with the interface. It’s crucial to pass the correct URL to fetch products, because it’s assigned to context.view and associated with the PLP.

export async function loader({request, params}: LoaderFunctionArgs) {
  const url = new URL(request.url);
  const {deserialize} = buildParameterSerializer();
  const parameters = deserialize(url.searchParams); 1

  listingEngineDefinition.setNavigatorContextProvider( 2
    () => new ServerSideNavigatorContextProvider(request)
  );

  const staticState = await fetchStaticState({ 3
    url: `${url.origin}/plp/${params['*']}`, 4
    parameters,
    k: 'listingEngineDefinition',
  });

  return {staticState};
}
PLP loader annotations
1 Deserialize the URL parameters using the buildParameterSerializer function.
2 Create a navigation context provider for the server side.
3 Fetch the static state for the listing page with the deserialized parameters as the initial value.
4 Specify the URL that corresponds to the product listing page you want to target.

Managing URL parameters

The Headless React package provides a ParameterManager controller that lets you manage URL parameters in your commerce application.

For more information, see managing parameters.

Define and retrieve a product list controller hook

While defining your commerce engine, use the defineProductList function to define and retrieve the target product list hook.

    productList: defineProductList(), 1
1 The productList controller provides search results as a list of products.

You can use the same useProductList hook for both search and listing pages.

Display listing page results with the listing provider

Render your listing page results using your hook on the ProductList controller, and wrap your components with your listing provider.

export default function PLP() {
  const {staticState} = useLoaderData<typeof loader>();
  const location = useLocation();
  const currentUrl = `${location.pathname}${location.search}${location.hash}`;

  return (
    <ListingProvider 1
      navigatorContext={new ClientSideNavigatorContextProvider()}
      staticState={staticState as ListingStaticState}
    >
      <ParameterManager url={currentUrl} />
      <section>
        <Sort />
        <Facets />
        <Breadcrumbs />
      </section>
      <section>
        <ProductList />
        <Pagination />
      </section>
    </ListingProvider>
  );
}
PLP component annotations
1 Wrap your components in a listing provider.