DEV Community

loading...
Commerce.js

Shoppable CMS with Commerce.js

Jamie Barton
Husband. Dad. Full Stack Developer.
Originally published at notrab.dev Updated on ・3 min read

Most of the time the Headless CMS is thought of as a place you fetch data from, or if your CMS supports it, a API to mutate data too. But, what if your CMS isn't the only source of truth for your data? What do we do if we want to connect content entries from one system to another?

Thankfully, APIs like GraphCMS allow you to embed datasources from other APIs into its own GraphQL Content API — Read more.

One of the most commonly created content types inside any CMS is going to be a Page, right?. These page entries typically contain titles, repeatable content blocks, related pages, SEO data, and much more.

It's also common to query data from multiple sources on a page at runtime, or during build. We could very easily query content from a CMS, and a commerce API separately.

With GraphCMS, you can fetch this data in a single GraphQL query. GraphCMS will take care of authenticating, and returning the data from any other content source you configure.

You can fetch all of the data for your content page, as well as the associated product(s), price, and images from Commerce.js.

GraphQL query to fetch pages with products

No matter your frontend, whether it be React, Vue, Angular, Svelte, or traditional server rendered pages, anywhere you can make a fetch request, you can now get all the data you need in one trip.

GraphCMS content federation request flow

The request to fetch products from the Commerce.js API also benefits from being strongly typed, self documenting, and works with GraphiQL autocomplete out of the box.

GraphiQL

How?

You'll need to use the GraphCMS Management SDK to generate the GraphQL types for Commerce.js, and create the remote field.

Here we'll create the type definitions:

const { newMigration, FieldType } = require("@graphcms/management");

const migration = newMigration({
  authToken: '...',
  endpoint: '..',
});

migration.createRemoteTypeDefinition({
  definition:
    "type ChecProductPrice { raw: Int!, formatted: String!, formatted_with_symbol: String!, formatted_with_code: String! }",
  displayName: "Chec Product Price",
  description: "Fields belonging to the Chec Product Price",
});

migration.createRemoteTypeDefinition({
  definition: "type ChecProductMedia { type: String, source: String }",
  displayName: "Chec Product Media",
  description: "Fields belonging to the Chec Product Media",
});

migration.createRemoteTypeDefinition({
  definition:
    "type ChecProduct { id: ID! name: String!, permalink: String!, price: ChecProductPrice!, media: ChecProductMedia }",
  displayName: "Chec Product",
  description: "Fields belonging to the Chec Product",
});
Enter fullscreen mode Exit fullscreen mode

We can also use the Management SDK to programmatically create our Page model, and fields.

const pageModel = migration.createModel({
  apiId: "Page",
  apiIdPlural: "Pages",
  displayName: "Page",
});

pageModel.addSimpleField({
  apiId: "title",
  displayName: "Title",
  description: "Give your page a title",
  type: FieldType.String,
  isRequired: true,
});

pageModel.addSimpleField({
  apiId: "content",
  displayName: "Content",
  type: FieldType.Richtext,
});

pageModel.addSimpleField({
  apiId: "checProductId",
  displayName: "Chec Product ID",
  description: "The ID of the Chec product this page relates to",
  type: FieldType.String,
});
Enter fullscreen mode Exit fullscreen mode

The field checProductId is what content editors will see when editing pages inside GraphCMS.

GraphCMS content editor

All that's left to with our Page model is add the remote field configuration, and run the migration.

Below we'll tell GraphCMS how to fetch data for the field checProduct, passing it the URL to the Commerce.js API, as well as our public key.

pageModel.addRemoteField({
  apiId: "checProduct",
  displayName: "Chec Product",
  remoteConfig: {
    url: "https://api.chec.io/v1/products/{checProductId}",
    headers: {
      "X-Authorization": 'YOUR CHEC PUBLIC KEY HERE',
    },
    method: "GET",
    returnType: "ChecProduct",
  },
});

migration.run()
Enter fullscreen mode Exit fullscreen mode

Try it yourself!

Click "run" below to fetch pages from GraphCMS with the associated Chec product.

// hidden setup JavaScript code goes in this preamble area require('graphql') const { gql, request } = require("graphql-request"); const endpoint = "https://api-eu-central-1.graphcms.com/v2/ckik2cgeykbl601xwam523kkb/master" const query = gql` { pages { title checProduct { id name permalink media { type source } price { raw formatted formatted_with_code } } } } ` request(endpoint, query).then(data => console.log(data))

That's it! 😎

If you're interested in trying this for yourself, you'll need an account with GraphCMS that supports Remote Fields, and an account with Chec (the API behind Commerce.js).

View example code on GitHub

Discussion (1)

Collapse
matfrana profile image
Matteo Frana

This is a way we could also integrate content like landing pages from React Bricks cms!