Build static product pages with Gatsby and Commerce.js
Tags: javascript, gatsby, ecommerce, jamstack
Published: 2020-04-21 14:50:20

---
title: Build static product pages with Gatsby and Commerce.js
published: true
description: Gatsby meet a developer-first eCommerce API.
tags: javascript, gatsby, ecommerce, jamstack
---

The JAMstack is a popular trend growing in the developer ecosystem today. With more and more sites taking advantage of deploying to the CDN, atomic deployments and leveraging APIs with JavaScript, it's no secret that eCommerce has been left behind!

Recently I discovered [Chec](http://chec.io), an eCommerce API with a developer-first [Commerce.js](https://commercejs.com/developers) library that takes care of the heavy lifting for you.

Whether you're running a digital store or delivering physical products, Chec (and Commerce.js) give you all of the handy helpers to get you going!

One of the biggest trends with those adopting the JAMstack is generating static pages at build time. One of the areas that's been left behind, and partly due to the increased build times, is eCommerce!

With Chec, and a static site generator like Gatsby, we can generate product pages ahead of time!

---

If you're familiar with Gatsby, you'll already be in love with its plugin ecosystem and querying for pages with GraphQL.

Having recently discovered Chec, I wanted to create a static site to showcase products and use their hosted checkout (storefront) for customers to pay and checkout.

![Chec Storefront](https://dev-to-uploads.s3.amazonaws.com/i/kptmsf9cjd3sqw9pjas9.png)

Using serverless functions, and webhooks, I can trigger all of the post checkout behaviour I want. This is what the JAMstack is all about, right?!

Chec didn't have an official source plugin, but one of their developers had a proof of concept in place. I decided to get to work and extend by submitting a pull request for categories, product and merchant nodes!

## Installing `gatsby-source-chec`

It's super easy to get going with Gatsby + Chec.

Inside your Gatsby project, run the following:

```bash
npm install @chec/gatsby-source-chec
# or
yarn add @chec/gatsby-source-chec 
```

Now, as you would configuring any Gatsby plugin, open `gatsby-config.js` and add the following to your `plugins` array.

```js
{
  resolve: '@chec/gatsby-source-chec',
    options: {
      publicKey: 'CHEC_PUBLIC_KEY'
    },
  },
```

⚠️ Replace `CHEC_PUBLIC_KEY` with your [Public API key](https://dashboard.chec.io/setup/developer).

### What does this do?

When we install the plugin, it tells Gatsby to run the plugin, and the `@chec/gatsby-source-chec` has been designed to create nodes for products, category and your merchant account.

This is then added to the GraphQL schema Gatsby creates on build. We can use this to query pages!

## Sourcing products with Gatsby

Gatsby exposes a [`createPages`](https://www.gatsbyjs.org/docs/node-apis/#createPages) API we can hook into to create pages programmatically.

Using `@chec/gatsby-source-chec` let's go ahead by running a query to our Chec and for each of the products we get, use the [`createPage`](https://www.gatsbyjs.org/docs/node-apis/#createPages) action to programmatically build a page!

```js
exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions;

  const {
    data: { products },
  } = await graphql(`
    {
      products: allChecProduct {
        nodes {
          id
          permalink
        }
      }
    }
  `);

  products.nodes.forEach(({ id, permalink }) =>
    createPage({
      path: `/products/${permalink}`,
      component: require.resolve(`./src/templates/ProductPage.js`),
      context: {
        id,
      },
    })
  );
};
```

## Creating static product pages with Gatsby

In the `createPages` API hook above, we said for each `products` `node` to `createPage` using the component `./src/templates/ProductPage.js`...

Let's create that component!

```js
// src/templates/ProductPage.js
import React from 'react';
import { graphql } from 'gatsby';

export default function ProductPage({ data: { product } }) {
  return (
    <React.Fragment>
      <h1>{product.name}</h1>
      <p>{product.price.formatted_with_symbol}</p>
    </React.Fragment>
  );
}

export const pageQuery = graphql`
  query ProductPageQuery($id: String!) {
    product: checProduct(id: { eq: $id }) {
      id
      name
      price {
        formatted_with_symbol
      }
    }
  }
`;
```

## Creating a static product index page

While this is great for creating pages for each of our products, we need a way to show all products...

Gatsby to the rescue! 🚀

Since we have the nodes already, we can use GraphQL to query for `allChecProduct`.

For the sake of this tutorial, let's also query for our Chec store name!

Go ahead and create a new file at `src/pages/index.js` and add the following:

```js
// src/pages/index.js
import React from 'react';
import { graphql, useStaticQuery, Link } from 'gatsby';

const pageQuery = graphql`
  {
    merchant: checMerchant {
      name: business_name
    }
    products: allChecProduct {
      nodes {
        name
        permalink
        price {
          formatted_with_symbol
        }
      }
    }
  }
`;

const IndexPage = () => {
  const { merchant, products } = useStaticQuery(pageQuery);

  return (
    <React.Fragment>
      <h1>{merchant.name}</h1>

      <h3>Products</h3>

      <ul>
        {products.nodes.map(product => (
          <li key={product.permalink}>
            <Link to={`/products/${product.permalink}`}>
              {product.name}: {product.price.formatted_with_symbol}
            </Link>
          </li>
        ))}
      </ul>
    </React.Fragment>
  );
};

export default IndexPage;
```

Voila! We now have a working index page for our products.

Don't believe me? Run `npm run develop` or `yarn develop` to see it in action!

## Build your own

* [Browse this example on GitHub](https://github.com/chec/gatsby-source-chec/tree/master/demo)
* [See plugin details](https://www.gatsbyjs.org/packages/@chec/gatsby-source-chec)
* [Contribute on GitHub](https://github.com/chec/gatsby-source-chec)