--- title: Build product listing pages (CSR) slug: p25a3258 canonical_url: https://docs.coveo.com/en/p25a3258/ collection: coveo-for-commerce source_format: adoc --- # Build product listing pages (CSR) Building [product listing pages (PLPs)](https://docs.coveo.com/en/m1sf3187/) with Coveo Headless involves two main elements: . Keeping the URL up to date as you navigate between pages using the [`Context`](https://docs.coveo.com/en/headless/latest/reference/interfaces/Commerce.Context.html) controller . Using the [`ProductListing`](https://docs.coveo.com/en/headless/latest/reference/interfaces/Commerce.ProductListing.html) controller to fetch product listings and display the results A complete example of a listing page component is available in the [sample project in the Headless repository](https://github.com/coveo/ui-kit/tree/master/packages/samples/headless-commerce-react/src/pages/product-listing-page.tsx). ## Prerequisite Make sure that you understand how to [build product listing pages (PLPs)](https://docs.coveo.com/en/o4ue0471/). ## Keep the URL up to date Keep the URL state updated in Headless to ensure that the correct [product listing page (PLP)](https://docs.coveo.com/en/m1sf3187/) is fetched when navigating between pages. The `context` helps Headless determine which [product listing page (PLP)](https://docs.coveo.com/en/m1sf3187/) to fetch products for. For more information, [Navigating between pages](https://docs.coveo.com/en/o7v87331/). ## Initializing the `ProductListing` controller After [initializing your engine](https://docs.coveo.com/en/o6r70022#initialize-the-headless-commerce-engine), you can pass in this instance to build the controller. ```tsx import { commerceEngine } from './Engine'; import { buildProductListing } from '@coveo/headless/commerce'; const productListing = buildProductListing(commerceEngine); ``` The `ProductListing` controller has a [`refresh`](https://docs.coveo.com/en/headless/latest/reference/interfaces/Commerce.ProductListing.html#refresh) method you can use to fetch product listings. ## Display the listing pages using the `ProductListing` controller In addition to ensuring that page navigation correctly updates the `url` using the `Context` controller, you must also display the products fetched by the `ProductListing` controller. ```tsx import { Cart, Search as HeadlessSearch, ProductListing, } from '@coveo/headless/commerce'; import { useState, useEffect } from 'react'; import FacetGenerator from '../../facets/facet-generator/facet-generator'; import Pagination from '../../pagination/pagination'; import ProductList from '../../product-list/product-list'; import Sort from '../../sort/sort'; interface ISearchAndListingInterface { searchOrListingController: HeadlessSearch | ProductListing; cartController: Cart; navigate: (pathName: string) => void; } export default function SearchAndListingInterface( props: ISearchAndListingInterface ) { const {searchOrListingController, cartController, navigate} = props; const [searchOrListingState, setSearchOrListingState] = useState( searchOrListingController.state ); useEffect(() => { <1> searchOrListingController.subscribe(() => setSearchOrListingState(searchOrListingController.state) ); }, [searchOrListingController]); return (