Hygraph - A GraphQL Driven CMS

Published: Jan 31, 2023 by Isaac Johnson

I first heard about Hygraph through TLDR. Hypgraph’s pitch is rather grand - a content management system that connects anything to anything. I was intrigued to say the least.

The general idea of a CMS is it exists to be the primary repository for content that drives apps, websites and other distribution systems:

/content/images/2023/01/CMS-Diagram.png

On a small scale, for instance, having a news website driven from a backend JSON file is sufficient. However, if you have many writers, with various review processes and a website, both free and paywalled, a mobile app and then various streams to partner media outlets, the simple “host a file” model starts to fall down.

History

Hygraph is a CMS platform that was formerly called GraphCMS. They were founded in 2015 by a team of data scientists and engineers with a passion for making sense of complex data sets.

Based out of Berlin, this German software company has upwards of 65 employees today and is privately held. GraphCMS was the brainchild of Daniel Winter (CTO) and Michael Lukaszczyk (CEO). They worked together at Canto, a Digital Asset Management company, before trying a new venture of “Lethal Webapps” that clearly didn’t take off (the URL now just redirects to Lethal Weapon on youtube)

That redirect has been up since 2018;

/content/images/2023/01/hypgraph-23.png

And the twitter account was last updated in 2016.

On GraphQL

GraphQL, a query language for APIs, is gaining traction as a modern alternative to REST. Developed and open-sourced by Facebook in 2015, GraphQL is a flexible powerful tool that allows developers to define and retrieve only the data they need, making it a popular choice for building efficient and scalable applications.

One of the main benefits of GraphQL is its ability to handle complex nested data structures. Unlike REST, which requires multiple endpoints to retrieve different data, GraphQL allows developers to request multiple fields in a single query, reducing the number of API calls and improving performance. This allows for more efficient data retrieval, especially for mobile and web applications, where network latency is a major concern.

Another advantage of GraphQL is its ability to handle real-time data. Its subscription feature allows developers to subscribe to updates in real-time, enabling the creation of dynamic and responsive apps. This makes GraphQL a popular choice for building real-time apps, such as chat apps and collaborative tools.

GraphQL is also gaining popularity among companies and organizations, who are using it to build robust and flexible APIs for their internal and external systems. This enables them to connect a wide range of data sources, such as databases, cloud services, and third-party APIs, into a single, unified interface.

Getting Started with Hygraph

We’ll click “Get started” on the main site

/content/images/2023/01/hypgraph-01.png

We can create a unique account or use a federated one. I’ll federate through an existing IdP provider

/content/images/2023/01/hypgraph-02.png

The next page will have a very fast paced Product Demo on YouTube before letting you move on to a Tour or just to the Welcome page

You can pick from a large list of prebaked templates, or you can create something new

/content/images/2023/01/hypgraph-03.png

I noted a lot of images still show the old product name of GraphCMS

/content/images/2023/01/hypgraph-04.png

I decided to try the Blog to start. Clicking create starts a deployment

/content/images/2023/01/hypgraph-05.png

Because I let it prefill some sample content, we can see some sample posts exist already

/content/images/2023/01/hypgraph-06.png

The API Playground let’s use browse the GraphQL structure. But best I can tell, this is just a fancy wrapper on JSON

/content/images/2023/01/hypgraph-07.png

The next step is to integrate a front-end

/content/images/2023/01/hypgraph-08.png

This brings us to a picklist of 5 NodeJS options

/content/images/2023/01/hypgraph-09.png

and they are mostly integration points with a few Node based frameworks (Next.js, Sveltkit, NuxtJS).

It isn’t bad, per se. I just was expecting something more like Zapier

NextJS

I’ll create a new NextJS app in a new directory locally and init it

builder@DESKTOP-72D2D9T:~/Workspaces$ cd nextJSTest/
builder@DESKTOP-72D2D9T:~/Workspaces/nextJSTest$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (nextjstest)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author: Isaac Johnson
license: (ISC) MIT

Then I’ll use npx to install next-app

builder@DESKTOP-72D2D9T:~/Workspaces/nextJSTest$ which npx
/home/builder/.nvm/versions/node/v17.6.0/bin/npx
builder@DESKTOP-72D2D9T:~/Workspaces/nextJSTest$ npx create-next-app@latest
✔ What is your project named? … my-app
✔ Would you like to use TypeScript with this project? … No / Yes
✔ Would you like to use ESLint with this project? … No / Yes
✔ Would you like to use `src/` directory with this project? … No / Yes
✔ Would you like to use experimental `app/` directory with this project? … No / Yes
✔ What import alias would you like configured? … @/*
Creating a new Next.js app in /home/builder/Workspaces/nextJSTest/my-app.

Using npm.

Installing dependencies:
- react
- react-dom
- next
- @next/font
- typescript
- @types/react
- @types/node
- @types/react-dom
- eslint
- eslint-config-next

added 271 packages, and audited 272 packages in 22s

102 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Initializing project with template: default

Success! Created my-app at /home/builder/Workspaces/nextJSTest/my-app

We can then cd into the directory to start the server

builder@DESKTOP-72D2D9T:~/Workspaces/nextJSTest/my-app$ ls
README.md  next-env.d.ts  next.config.js  node_modules  package-lock.json  package.json  public  src  tsconfig.json
builder@DESKTOP-72D2D9T:~/Workspaces/nextJSTest/my-app$ npm run dev

> my-app@0.1.0 dev
> next dev

ready - started server on 0.0.0.0:3000, url: http://localhost:3000
event - compiled client and server successfully in 2.3s (165 modules)
Attention: Next.js now collects completely anonymous telemetry regarding usage.
This information is used to shape Next.js' roadmap and prioritize features.
You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
https://nextjs.org/telemetry

/content/images/2023/01/hypgraph-10.png

To use Hygraph, I’ll need to add the GraphQL Libraries

builder@DESKTOP-72D2D9T:~/Workspaces/nextJSTest/my-app$ npm install graphql-request graphql

added 15 packages, and audited 287 packages in 4s

103 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

I tried initially just changing the “Products” area over to “Posts” and adding a QUERY block

$ cat src/pages/index.js
import Link from 'next/link';
import { GraphQLClient } from 'graphql-request';
import { gql } from 'graphql-request';

const QUERY = gql`
  {
    posts {
      id
      title
    }
  }
`

export async function getStaticProps() {
  const hygraph = new GraphQLClient(
    'https://api-us-east-1-shared-usea1-02.hygraph.com/v2/claaaaeeefffaaaeeeffaaaeeeff36/master'
  );

  const { products } = await hygraph.request(QUERY)

  return {
    props: {
      posts
    },
  };
}

export default ({ posts }) => (
  <ul>
  posts.map(({ id, title }) => (
      <li key={id}>{title}</li>
    ))
  </ul>
)

But it vomited, ultimately because the sample code wasn’t ready for Node 17

I pivotted and used their example repo instead of my newly created one. I did the same test with the same results.

I reverted my changes, just in case I made a typo

builder@DESKTOP-72D2D9T:~/Workspaces/hygraph-examples/with-nextjs$ git checkout -- src/pages/index.js

and tried again

builder@DESKTOP-72D2D9T:~/Workspaces/hygraph-examples/with-nextjs$ npm run dev

> dev
> next

Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
ready - started server on http://localhost:3000
node:internal/crypto/hash:67
  this[kHandle] = new _Hash(algorithm, xofLen);
                  ^

Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:67:19)
    at Object.createHash (node:crypto:135:10)
    at module.exports (/home/builder/Workspaces/hygraph-examples/with-nextjs/node_modules/webpack/lib/util/createHash.js:135:53)
    at NormalModule._initBuildHash (/home/builder/Workspaces/hygraph-examples/with-nextjs/node_modules/webpack/lib/NormalModule.js:417:16)
    at handleParseError (/home/builder/Workspaces/hygraph-examples/with-nextjs/node_modules/webpack/lib/NormalModule.js:471:10)
    at /home/builder/Workspaces/hygraph-examples/with-nextjs/node_modules/webpack/lib/NormalModule.js:503:5
    at /home/builder/Workspaces/hygraph-examples/with-nextjs/node_modules/webpack/lib/NormalModule.js:358:12
    at /home/builder/Workspaces/hygraph-examples/with-nextjs/node_modules/loader-runner/lib/LoaderRunner.js:373:3
    at iterateNormalLoaders (/home/builder/Workspaces/hygraph-examples/with-nextjs/node_modules/loader-runner/lib/LoaderRunner.js:214:10)
    at Array.<anonymous> (/home/builder/Workspaces/hygraph-examples/with-nextjs/node_modules/loader-runner/lib/LoaderRunner.js:205:4) {
  opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED'
}

Node.js v17.6.0

I tried to upgrade packages in case out-of-date dependencies was the cause of the errors

builder@DESKTOP-72D2D9T:~/Workspaces/hygraph-examples/with-nextjs$ npm upgrade
npm WARN deprecated source-map-url@0.4.1: See https://github.com/lydell/source-map-url#deprecated
npm WARN deprecated @npmcli/move-file@1.1.2: This functionality has been moved to @npmcli/fs
npm WARN deprecated chokidar@2.1.8: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies
npm WARN deprecated querystring@0.2.1: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.

added 192 packages, removed 221 packages, changed 249 packages, and audited 774 packages in 24s

40 packages are looking for funding
  run `npm fund` for details

20 vulnerabilities (3 moderate, 13 high, 4 critical)

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

then run

builder@DESKTOP-72D2D9T:~/Workspaces/hygraph-examples/with-nextjs$ npm run dev

> dev
> next

Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
ready - started server on http://localhost:3000
node:internal/crypto/hash:67
  this[kHandle] = new _Hash(algorithm, xofLen);
                  ^

Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:67:19)
    at Object.createHash (node:crypto:135:10)
    at module.exports (/home/builder/Workspaces/hygraph-examples/with-nextjs/node_modules/webpack/lib/util/createHash.js:135:53)
    at NormalModule._initBuildHash (/home/builder/Workspaces/hygraph-examples/with-nextjs/node_modules/webpack/lib/NormalModule.js:417:16)
    at handleParseError (/home/builder/Workspaces/hygraph-examples/with-nextjs/node_modules/webpack/lib/NormalModule.js:471:10)
    at /home/builder/Workspaces/hygraph-examples/with-nextjs/node_modules/webpack/lib/NormalModule.js:503:5
    at /home/builder/Workspaces/hygraph-examples/with-nextjs/node_modules/webpack/lib/NormalModule.js:358:12
    at /home/builder/Workspaces/hygraph-examples/with-nextjs/node_modules/loader-runner/lib/LoaderRunner.js:373:3
    at iterateNormalLoaders (/home/builder/Workspaces/hygraph-examples/with-nextjs/node_modules/loader-runner/lib/LoaderRunner.js:214:10)
    at Array.<anonymous> (/home/builder/Workspaces/hygraph-examples/with-nextjs/node_modules/loader-runner/lib/LoaderRunner.js:205:4) {
  opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED'
}

Node.js v17.6.0

But it didn’t like the code for NodeJS v17

I went back to using v14.19.0. This proved to be much more successful.

/content/images/2023/01/hypgraph-11.png

builder@DESKTOP-72D2D9T:~/Workspaces/hygraph-examples/with-nextjs$ npm run dev

> hygraph-with-nextjs@ dev /home/builder/Workspaces/hygraph-examples/with-nextjs
> next

Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
ready - started server on http://localhost:3000

I added my code with the ql as a const, but that particular line failed;

/content/images/2023/01/hypgraph-12.png

It’s not pretty, but using the following for index.tpx will show the posts as a bulleted list.

builder@DESKTOP-72D2D9T:~/Workspaces/hygraph-examples/with-nextjs$ cat src/pages/index.js
import Link from 'next/link';
import { GraphQLClient } from 'graphql-request';

export async function getStaticProps() {
  const hygraph = new GraphQLClient(
    'https://api-us-east-1-shared-usea1-02.hygraph.com/v2/claaaaeeefffaaaeeeffaaaeeeff36/master'
  );

  const { posts } = await hygraph.request(
    `
  {
    posts {
      id
      title
    }
  }
    `
  );

  return {
    props: {
      posts,
    },
  };
}

export default ({ posts }) =>
  posts.map(({ id, title }) => (
      <li key={id}>{title}</li>
    ));

Running

builder@DESKTOP-72D2D9T:~/Workspaces/hygraph-examples/with-nextjs$ npm run dev

> hygraph-with-nextjs@ dev /home/builder/Workspaces/hygraph-examples/with-nextjs
> next

Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
ready - started server on http://localhost:3000
event - compiled successfully
event - build page: /
wait  - compiling...
warn  - ./src/pages/index.js
Anonymous arrow functions cause Fast Refresh to not preserve local component state.
Please add a name to your function, for example:

Before
export default () => <div />;

After
const Named = () => <div />;
export default Named;

A codemod is available to fix the most common cases: https://nextjs.link/codemod-ndc
info  - ready on http://localhost:3000

/content/images/2023/01/hypgraph-13.png

And we can see this matches what I have the CMS presently

/content/images/2023/01/hypgraph-14.png

NuxtJS

I decided to pivot and try another example library - NuxtJS.

Before I change anything, I’ll set my env to Node14 and do a test install and run

builder@DESKTOP-QADGF36:~/Workspaces/hygraph-examples$ nvm list
->     v10.22.1
      v12.22.11
       v14.18.1
        v17.6.0
default -> 10.22.1 (-> v10.22.1)
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v17.6.0) (default)
stable -> 17.6 (-> v17.6.0) (default)
lts/* -> lts/gallium (-> N/A)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.12 (-> N/A)
lts/fermium -> v14.19.1 (-> N/A)
lts/gallium -> v16.14.2 (-> N/A)
builder@DESKTOP-QADGF36:~/Workspaces/hygraph-examples$ nvm use 14.18.1
Now using node v14.18.1 (npm v6.14.15)

Then install packages

builder@DESKTOP-QADGF36:~/Workspaces/hygraph-examples/with-nuxtjs$ npm install
npm WARN deprecated core-js@2.6.12: core-js@<3.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.
npm WARN deprecated @npmcli/move-file@1.1.2: This functionality has been moved to @npmcli/fs
npm WARN deprecated svgo@1.3.2: This SVGO version is no longer supported. Upgrade to v2.x.x.
npm WARN deprecated chokidar@2.1.8: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies
npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
npm WARN deprecated stable@0.1.8: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility
npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.

> core-js@2.6.12 postinstall /home/builder/Workspaces/hygraph-examples/with-nuxtjs/node_modules/core-js
> node -e "try{require('./postinstall')}catch(e){}"

Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!

The project needs your help! Please consider supporting of core-js on Open Collective or Patreon:
> https://opencollective.com/core-js
> https://www.patreon.com/zloirock

Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)


> nuxt@2.15.8 postinstall /home/builder/Workspaces/hygraph-examples/with-nuxtjs/node_modules/nuxt
> opencollective || exit 0

                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
                     @@@@@@@@@@@@@@@%##%@@@@@@@@@@@@@@@@@@@@@
                     @@@@@@@@@@@@@@#+++*%@@@%%%@@@@@@@@@@@@@@
                     @@@@@@@@@@@@@#++*++*%@%*+*#@@@@@@@@@@@@@
                     @@@@@@@@@@@%#++*%%*++#*++++#%@@@@@@@@@@@
                     @@@@@@@@@@%*++#%@@%*+++*%#++*%@@@@@@@@@@
                     @@@@@@@@@%*++#@@@@@#++*%@@#++*%@@@@@@@@@
                     @@@@@@@@%*++#@@@@%#++*%@@@@#++*%@@@@@@@@
                     @@@@@@@#+++#%%%%#*++#%@%%%%%#+++#@@@@@@@
                     @@@@@@%*++++++++++*#@%#+++++++++*%@@@@@@
                     @@@@@@@%########%%%@@%##########%@@@@@@@
                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

                         Thanks for installing nuxtjs 🙏
                 Please consider donating to our open collective
                        to help us maintain this package.

                            Number of contributors: 0
                              Number of backers: 504
                             Annual budget: $122,594
                             Current balance: $13,845

           👉  Donate: https://opencollective.com/nuxtjs/donate

npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@~2.3.2 (node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.2.7 (node_modules/watchpack-chokidar2/node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

added 1409 packages from 611 contributors and audited 1411 packages in 33.563s

119 packages are looking for funding
  run `npm fund` for details

found 5 high severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details

Then when run

builder@DESKTOP-QADGF36:~/Workspaces/hygraph-examples/with-nuxtjs$ npm run dev

> hygraph-with-nuxtjs@ dev /home/builder/Workspaces/hygraph-examples/with-nuxtjs
> nuxt


ℹ NuxtJS collects completely anonymous data about usage.                                                                               15:57:22
  This will help us improve Nuxt developer experience over time.
  Read more on https://git.io/nuxt-telemetry

? Are you interested in participating? No


   ╭───────────────────────────────────────╮
   │                                       │
   │   Nuxt @ v2.15.8                      │
   │                                       │
   │   ▸ Environment: development          │
   │   ▸ Rendering:   server-side          │
   │   ▸ Target:      server               │
   │                                       │
   │   Listening: http://localhost:3000/   │
   │                                       │
   ╰───────────────────────────────────────╯

ℹ Preparing project for development                                                                                                    15:57:26
ℹ Initial build may take a while                                                                                                       15:57:26
✔ Builder initialized                                                                                                                  15:57:26
✔ Nuxt files generated                                                                                                                 15:57:26

● Client █████████████████████████ building (28%) 151/173 modules 22 active

● Client █████████████████████████ building (29%) 164/174 modules 10 active

● Client █████████████████████████ building (29%) 166/179 modules 13 active

● Client █████████████████████████ building (31%) 178/194 modules 16 active
 node_modules/core-js/modules/_shared-key.js


● Client █████████████████████████ building (31%) 183/199 modules 16 active
 node_modules/core-js/modules/_array-species-constructor.js

● Server █████████████████████████ building (16%) 50/52 modules 2 active

● Client █████████████████████████ building (32%) 189/199 modules 10 active
 node_modules/core-js/modules/_array-species-constructor.js

● Server █████████████████████████ building (16%) 57/59 modules 2 active

● Client █████████████████████████ building (34%) 207/216 modules 9 active
 css-loader › vue-loader › postcss-loader › vue-loader › .nuxt/components/nuxt-build-indicator.vue

● Server █████████████████████████ building (16%) 57/59 modules 2 active
 babel-loader › vue-loader › vue-loader › .nuxt/components/nuxt-build-indicator.vue

● Client █████████████████████████ building (35%) 214/219 modules 5 active
 node_modules/@babel/runtime/helpers/esm/classCallCheck.js

● Server █████████████████████████ building (17%) 59/60 modules 1 active
 node_modules/vue-style-loader/lib/listToStyles.js

● Client █████████████████████████ building (36%) 218/223 modules 5 active
 node_modules/@babel/runtime/helpers/esm/taggedTemplateLiteral.js

● Server █████████████████████████ emitting (95%) vue-server-plugin


● Client █████████████████████████ building (36%) 222/223 modules 1 active
 node_modules/@babel/runtime/helpers/esm/taggedTemplateLiteral.js

✔ Server
  Compiled successfully in 3.02s

● Client █████████████████████████ building (38%) 241/241 modules 0 active


✔ Server
  Compiled successfully in 3.02s

● Client █████████████████████████ additional chunk assets processing (90%)


✔ Server
  Compiled successfully in 3.02s

● Client █████████████████████████ emitting (95%) HtmlWebpackPlugin


✔ Server
  Compiled successfully in 3.02s

✔ Client
  Compiled successfully in 3.28s

✔ Server
  Compiled successfully in 3.02s


 WARN  You did not set any plugins, parser, or stringifier. Right now, PostCSS does nothing. Pick plugins for your case on https://www.postcss.parts/ and use them in postcss.config.js.


 WARN  You did not set any plugins, parser, or stringifier. Right now, PostCSS does nothing. Pick plugins for your case on https://www.postcss.parts/ and use them in postcss.config.js.


 WARN  You did not set any plugins, parser, or stringifier. Right now, PostCSS does nothing. Pick plugins for your case on https://www.postcss.parts/ and use them in postcss.config.js.


 WARN  You did not set any plugins, parser, or stringifier. Right now, PostCSS does nothing. Pick plugins for your case on https://www.postcss.parts/ and use them in postcss.config.js.


 WARN  You did not set any plugins, parser, or stringifier. Right now, PostCSS does nothing. Pick plugins for your case on https://www.postcss.parts/ and use them in postcss.config.js.


 WARN  You did not set any plugins, parser, or stringifier. Right now, PostCSS does nothing. Pick plugins for your case on https://www.postcss.parts/ and use them in postcss.config.js.

ℹ Waiting for file changes                                                                                                             15:57:30
ℹ Memory usage: 172 MB (RSS: 261 MB)                                                                                                   15:57:30
ℹ Listening on: http://localhost:3000/

We see it render some products

/content/images/2023/01/hypgraph-25.png

I changed the URL to my Hygraph endpoint in plugins/hygraph.js then updated the index.vue

<template>
  <div class="container mx-auto text-center">
    <div class="pt-4">
      <h2 class="text-xl">Nuxt with Hygraph</h2>
      <div class="flex justify-center -mx-4 my-4">
        <router-link
          v-for="post in posts"
          :to="{ title: 'post-slug', params: { title: post.title } }"
          :key="post.id"
        >
          <article class="border rounded-md p-6 mx-2">
            <h1 class="fopnt-bold text-xl"></h1>
          </article>
        </router-link>
      </div>
    </div>
  </div>
</template>

<script>
import { gql } from 'graphql-request';

export default {
  async asyncData({ $hygraph }) {
    const { posts } = await $hygraph.request(
      gql`
        {
          posts {
            id
            title
          }
        }
      `
    );

    return { posts  };
  },
};
</script>

Running npm run dev we can now see our posts

/content/images/2023/01/hypgraph-26.png

We added a “Page” last time. Now let’s add a “Post” so we can see a live example:

Adding content

Content is largely dependent on your schema. For the blog, we can see we have Author, Page, Post and SEO

/content/images/2023/01/hypgraph-15.png

If I wish to add a new Author, I can click the “+ Add entry” button to do so

/content/images/2023/01/hypgraph-20.png

I can add a picture and even crop it inline

/content/images/2023/01/hypgraph-16.png

I’ll setup the Bio and Title and have a nice Author page

/content/images/2023/01/hypgraph-17.png

When you save, you essentially stage the change. To make a thing live, you must “Publish”

/content/images/2023/01/hypgraph-18.png

Since everything is an asset, it will catch related unpublished things (like the Bio picture) to also optionally publish

/content/images/2023/01/hypgraph-19.png

Writing content

In our blog example, we have the ability to create a Post which will have “content” which is much richer than say a Slug or Author Title.

Here we have the Content Editor wizard which has some nice WYSIWYG controls

/content/images/2023/01/hypgraph-21.png

Which we can use in writing content (or letting ChatGPT write some blurbs)

/content/images/2023/01/hypgraph-22.png

Webhooks

We have the ability to add webhooks. Here I was expecting to see some template examples - perhaps slack, teams or others, but it’s a pretty raw form.

/content/images/2023/01/hypgraph-24.png

I really don’t know what would get passed - I likely would need to discover it with a webhook receiver that could dump the payload (I’ve used AzDO Webhooks for this before).

Usage and Costs

We can check our projects at any time for current usage. There is a free, albeit limited, tier:

/content/images/2023/01/hypgraph-29.png

This gives us 3 seats and a rather generous 1M API calls.

If we click “Upgrade Plan” we can see the pricing options.

/content/images/2023/01/hypgraph-30.png

Note, the prices are in “Annual” billing.. Moving to monthly, we see:

/content/images/2023/01/hypgraph-31.png

Summary

Hygraph definitely fills a niche - a CMS backend that really doesn’t offer a prebaked rich front-end, rather simplified integrations with example code. That is, Hygraph focuses entirely on your backend. For many companies, this might be the key piece they really need.

The struggle, I believe, is finding that company that has solved their front-ends quite well but needs the drop-in backend only. I could imagine businesses that outsource the front-end to UI shops or low-cost centers and want to keep the IP/backend in-country. I could also see growth issues with larger enterprises that need a scalable backend for their already-existing front-ends.

In looking at Hygraph, one should think about other options as well; such as using serverless Azure Functions that could use Apollo to expose a backend tied to Cosmos or other DBs. This example just exposes a hardcoded string, but you get the idea.

GCP based systems would likely use Apigee API Management to expose GraphQL. Lastly, there are other GraphQL-based competitors such as Contentful and DotCMS (though the later has rather high prices).

The two biggest advantages I see with Hygraph is the large catalogue of example code and a decent usable free tier. Free tiers, even with limitations, allow developers, such as myself, to really take it out for a spin.

cms hygraph graphql

Have something to add? Feedback? You can use the feedback form

Isaac Johnson

Isaac Johnson

Cloud Solutions Architect

Isaac is a CSA and DevOps engineer who focuses on cloud migrations and devops processes. He also is a dad to three wonderful daughters (hence the references to Princess King sprinkled throughout the blog).

Theme built by C.S. Rhymes