Add shop pages

You've made it easy for buyers to find the shops on your marketplace through the homepage. Now you want your marketplace to provide shop details and their products, in dedicated shop pages.

In this tutorial, you'll learn how to create dynamic routing that directs buyers to a unique URL for each shop in the marketplace. When buyers select a shop from the homepage, they can see store details and products that the merchant has published to the marketplace.

An image of the shop page you'll create in this tutorial

What you'll learn

After finishing this tutorial, you'll know how to do the following:

  • Add unique URLS for the shop in your marketplace

  • Display shop details and products on a single page in the marketplace

Requirements

Step 1: Add dynamic routing

Dynamic routing enables a unique URL for storefront pages in your marketplace. You'll construct the URL using the unique shop ID that you stored in the database, as /shops/[ID].

In this step, you'll use Next.js to add dynamic routes by setting brackets on a page name.

  1. In pages/, create a shops folder for the shop page subroutes.

  2. In pages/shops/, create an [id].js file.

    Navigating to your ngrok URL /shops/1 route should render a simple page that looks something like the following:

    An image of a basic shop page that says Shop: 1

Step 2: Add the shop field to the internal GraphQL API

To retrieve data for a single store in the marketplace, you'll need a method of retrieving the domain and Storefront API access token, given the shop ID from the URL. To accomplish this, you'll add a field to the internal GraphQL API that you created to return shop details by ID.

  1. In server/graphql/schema.js, add a Shop field to the GraphQL API schema's query root with a required id argument and a return of type Shop.

  2. In server/graphql/resolvers.js, add an argument to filter database queries by shop ID.

    Because the shop data model matches the Shop type in the GraphQL API schema, Apollo Server automatically returns the shop properties that match the field names.

    You should be able to query for a shop by ID in the GraphQL playground, available in your app at the /graphql path.

    An image of the GraphQL Playground showing a query for a shop by ID and the result

  3. In pages/shops/[id].js, query the field to retrieve the shop domain and Storefront API access token using the ID from the router query.

  4. Create an ApolloClient to query the Storefront API using the domain and Storefront API access token.

Step 3: Display shop information

After storefront client is in the component state, you can retrieve the shop data from the Storefront API. You'll need to store the data in your component's state and add an effect to retrieve the data using the storefront client is created.

If the shop data is not yet available, you'll render a loading state. After the shop data is returned, you can render the shop name, description, and a link to the storefront.

  1. In pages/shops/[id].js, add a Storefront API query to retrieve the shop information.

    The response returns the shop name, description, and the primary domain's URL and host.

  2. Store the data in your component's state with an effect to retrieve the data when the client is created.

    The return data will be used to render the shop name, description, and a link to the storefront.

    The shop page should now look something like the following:

    An image of the shop page that includes the name, link to the online store, and description

Step 4: Display shop products

Fetch a list of products from the shop and render them in a paginated list to help buyers navigate the content. For pagination, your GraphQL queries will accept the first, last, before, and after arguments. You'll retrieve product details and the page information and cursor, which are also necessary for pagination.

  1. In pages/shops/[id].js query the Storefront API to retrieve shop information.

    The response body returns the product details, and the page info and cursor that are required for pagination.

  2. Create a PaginatedProducts component that does the following:

    • Accepts the list of products returned from the query
    • Renders a product grid with links to the previous and next pages

    The links to the Previous and Next pages include the before and after query parameters with the cursor.

  3. Add a ProductSection component that accepts a storefront client that can query product information from the Storefront API.

    The component should query the Storefront API to fetch products, using the before and after query parameters from the router query, and store the result in state. The product data from state can be used to render the PaginatedProducts component that you created.

  4. In the ProductSection component, add an effect that sets the product data in the component state to null when the before and after parameters change.

    This a performance optimization that triggers the loading state when buyers are navigating between pages.

  5. Update the default component to return the ProductSection component.

    The shop page of your marketplace should now look something like the following:

    An image of the shop page that you created in this tutorial

Previously, you set up the homepage to redirect buyers to merchant's online store URL. In this step, you'll update the link to redirect buyers to the merchant's shop page on your marketplace.

  1. In pages/index.js, update the ShopSection component to redirect to the merchant's shop page using a next/link.

    Since the id field is already included in the shops query, and the shop returned from the query is spread into the ShopSection component, id will be available as a property.

Your homepage should now contain links to your shop pages:

A gif showing the homepage with a link that redirects to the shop page

Next steps